Java: A platform for platforms
Sun's reorg may seem promising to shareholders but it's also a scramble for position. The question now is whether Sun can, or wants to, maintain its hold on Java technology. Especially with enterprise leaders like SpringSource and RedHat investing heavily in Java's future as a platform for platforms

Also see:

Discuss: Tim Bray on 'What Sun Should Do'

Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Can you securely read a password on the command line?

Securely reading a password from the command line in Java is difficult, but there are some (imperfect) solutions

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Q

I need to read passwords from the command line. Is there a way to easily read characters from the command line securely in Java? Specifically, how do you echo * to the command line?

AI've seen that question many times. Unfortunately, there does not appear to be a way to securely accept passwords on the command line from within a Java program by simply using the supplied Java APIs. Let's look at why that is the case.

To read items in from the command line, we use the input stream System.in. If we dig into the code a bit, we see that the default System.in input stream is really just an InputStream. Digging into my implementation of Java (IBM 1.1.7), the true implementation type of that System.in is a FileInputStream. That input stream is set to read in from the source file descriptor FileDescriptor.in. However, FileDescriptor.in is initialized by natively defined code. It is left to the system to point the FileDescriptor.in at the standard input handle.

If we look at the API definition for FileInputStream, we see that the read method is natively defined. Typed data is not taken from the command line and made available from the standard in file descriptor until the return button is pressed. Since we cannot grab a character as it is typed, there is no way to intercept the character and echo a * to the command line. Instead, we can only grab complete lines.

That leaves us with few alternatives. Unfortunately, most of the solutions require us to dive into native code or employ a GUI frontend. Briefly, here are a few solutions:

About the author

Tony Sintes is a senior consultant at ObjectWave Corporation who specializes in telecommunications. Tony has worked with Java since 1997 and is a Sun-certified Java 1.1 programmer and Java 2 developer.
  1. Forgo a command-line-based username/password interface. Instead, use a graphical frontend. Swing provides for protected text fields. Of course, that approach is useless if you plan to deploy on a terminal or another nongraphical environment.
  2. Forget writing that piece of your application in Java. Instead, write a process based on C or C++ that reads from the command line. Your Java application can talk to that process over the wire through sockets or some other protocol such as CORBA. There are some disadvantages to that approach: first, you must recompile the code for each deployment environment. Second, you'll need to encrypt the password since it may pass over the network.
  3. Write your own JNI command line reader and call it from your code, thus bypassing the input stream. Again, you'll need to recompile your library for each platform.
  4. If you feel really adventurous, you can always extend FileInputStream and provide your own read() implementation.


  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources