...
This compliant solution uses the Console.readPassword()
method to obtain the password from the console.:
Code Block | ||
---|---|---|
| ||
class Password { public static void main (String args[]) throws IOException { Console c = System.console(); if (c == null) { System.err.println("No console."); System.exit(1); } String username = c.readLine("Enter your user name: "); char[] password = c.readPassword("Enter your password: "); if (!verify(username, password)) { throw new SecurityException("Invalid Credentials"); } // Clear the password Arrays.fill(password, ' '); } // Dummy verify method, always returns true private static final boolean verify(String username, char[] password) { return true; } } |
...
Code Block | ||
---|---|---|
| ||
void readData() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("file")));
// Read from the file
String data = br.readLine();
} |
The BufferedReader.readLine()
method returns the sensitive data as a String
object, which can persist long after the data is no longer needed. The BufferedReader.read(char[], int, int)
method can read and populate a char
array. However, it requires the programmer to manually clear the sensitive data in the array after use. Alternatively, even if the BufferedReader
were to wrap a FileReader
object, it would suffer from the same pitfalls.
...
Code Block | ||
---|---|---|
| ||
void readData() { ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); try (FileChannel rdr = (new FileInputStream("file")).getChannel()) { while (rdr.read(buffer) > 0) { // Do something with the buffer buffer.clear(); } } catch (Throwable e) { // Handle error } } |
...
Bibliography
[API 2013] | Class ByteBuffer |
[Oracle 2012b2013b] | Reading ASCII Passwords from an InputStream Example (Java Cryptography Architecture [JCA] Reference Guide) |
[Tutorials 20082013] | I/O from the Command Line |
...