Java – Console
To get sensitive user input without echoing it to the console/terminal, the Java SDK has introduced the java.io.Console class. The Console class is quite unique in the way it handles its data. It uses the native encoding of the system instead of the using the JVM’s default encoding.
The Console class provides methods to access the console/terminal, if any is associated with the JVM.
Using the Console class:
So how do you use the Console class ? Its pretty simple really. First get a reference to the Console class from the System class
Console con = System.console();
It is not always possible to get a reference to the console. Some scenarios prevent the developer from gaining access to the console. This method may return null in these cases. For example a batch process running on a server will not expect user input and usually does have a console. Your code must be capable of handling such situations.
Consider that you have a program that requires the user to secretly type in his/her password.
Entering sensitive data through the console:
Console con = System.console(); String user = con.readLine("Username: "); char[] password = con.readPassword("Password: ");
If you were to run this code using the eclipse IDE it would not work (At least in eclipse 3.2).
This is because eclipse does not handle this code properly as yet. Run this code from the command prompt for now. Here is the output of the program
Output:
java com.Tests.Cert Username: hello Password:
Even though the output does not show a password being typed in, the user has typed it in on the console. The console’s feature allows the user to type in the password without it being echoed to the screen.
The line of code con.readLine(“Username: “); reads data from the console normally and stores it into a string. It also echoes whatever the user types onto the screen (you can see “hello” on the output). The line of code con.readPassword(“Password: “); prompts the user for a password but does not echo the contents of the password to the screen. This allows the user to enter his/her password safely using the Console class. To format the output to the screen the following code can be used.
Formatting data:
Console con = System.console(); String user = con.readLine("Welcome %s. Please login \nUsername:","Guest"); char[] password = con.readPassword("What is your password %s:",user); System.out.println("User: " + user ); System.out.println("Password: " + new String (password) );
Output:
java com.Tests.Cert Welcome Guest. Please login Username: hello What is your password hello: User: hello Password: bla
Notice that although the password is not visible in the console screen, the program was able to retrieve it. Also the line of code con.readPassword(“What is your password %s: “,user); will format the output such that the username is present when asking for the password. %s represents the String that was passed to the method. Now let’s take a look at using the format() method.
Formatting output only:
Console con = System.console(); con.format("Welcome %s \n", "Mr bond"); String user = con.readLine("Username: "); char[] password = con.readPassword("What is your password %s:",user); System.out.println("User: " + user ); System.out.println("Password: " + new String (password) );
Output:
Welcome Mr bond Username: 007 What is your password 007: User: 007 Password: goldeneye
In this case the formatting that was present in the readLine() method has been transferred to the format() method. Console also has a printf() method that works similar to the format() method. This method however has been made available only for convenience. Finally you can make use of the reader and writer classes to read and write to the Console.
Reader and Writer:
Note: This code throws IOException since we need read/write access to the console
char buffer[]= new char[1024]; Console con = System.console(); Reader reader = con.reader(); int numRead = reader.read(buffer); // #1 System.out.println(new String (buffer).substring(0, numRead) ); Writer writer = con.writer(); // #2 writer.write(buffer); writer.flush(); writer.close();
Output:
reader -- #a. Input provided by a user reader -- #b. Written by System.out reader -- #c. Written by console writer
The #a reader is the input that was provided to the program. The program reads this data using the Reader class. It reads the data into a character buffer in line #1 and prints the data to the console . At line #2 the console’s writer is obtained by the program and the contents of the character buffer are sent to the console output again (this time using System.out). Be wary however, when you use the Reader and Writer classes. They throw the IOException and since this is a checked Exception it must be handled. The code above throws this exception from a method (not shown) and thus need not handle it.
Hi,
First of all, thanks for this post.
BTW, you can also mention the fact that since readPassword returns a char array and not a string(like readLine) the password will not be pooled and hence it is considered a safer method than readLine().
@Monu
You are welcome.
I am not sure if readLine() sends Strings to a pool, and even if it did, it is not necessarily any safer. I am not aware of a scenario where an outsider would be allowed to read java’s internal String pool.
Thanks for sharing your thoughts
You are right, the string returned by readLine() might not go to the constant string pool. However, it remains in heap.
There is a little security note in the description of the Console class that reads:
If an application needs to read a password or other secure data, it should use readPassword() or readPassword(String, Object…) and manually zero the returned character array after processing to minimize the lifetime of sensitive data in memory.
What I said was based on the above statement-perhaps too much thinking and assumptions.
You are right. Strings are immutable and they remain in the heap until the garbage collector takes over. And when they are in the heap, they can be read by some profiling tools and heap analyzers.
However this is a great post. Thanks for putting this up.
@James
@Monu
ah ! a good point. You should still be able to sniff the heap data. I have to agree that getting rid of the reference as soon as possible is a good idea.
It very good article which never came across before. Good job…
Your blog is informative and good to spend
Good post.
This article helped me a lot to understand the facts of Console class and that too very easily.
Thanks a lot!!!
@Yousuff
Thanks Yousuff.
@Sonika
I am glad you found it useful. Thank you for leaving a comment
Very Useful!
I didn’t found any other reference instead of the Java API.
Congrat’s
@Luciano
I am glad you found it useful. Thank you for leaving your thoughts here
Just in time before I take my certification exam. Good article/tutorial. Thanks!
thanks CertPal
post is very useful
good discussion
thanks for the efforts
Thanks,
Always useful info
Thanks for the info. Yet another scenario where heap is readable is JVM crash with core dump.Core dump will have whatever was in heap at the time.
I like what you guys are up too Such smart work and reporting! Carry on the superb works guys I’ve incorporated you guys to my blogroll I think it will improve the value of my website