Oneof the ongoing criticisms of the Java command line text-basedinput/output APIs is the lack of support for command line inputpassword masking. With AWT/Swing, this is not a problem as methods areprovided to mask passwords easily.
An earlier version of this article was published here in September2002, and since then numerous letters of thanks, constructive comments,and permissions to use the source code in applications have beenreceived. This article:
If you wish to provide a graphical login dialog box for your application, you can use the AWT's TextField class, which is a text component that allows the editing of a single line of text. To mask the password field, use the setEchoChar method. For example, to set the echo char to an asterisk, you would do:
The number 8 specifies the width of the text field based on theaverage character width for the font in use. You can set the echocharacter to any character you like. Note that if you set it to zero, 0, it means that the input will be echoed and not masked.
In Swing, you can use the JPasswordField, whichallows the editing of a single line of text where the view indicatessomething was typed, but does not show the original characters. The JPasswordField class is source-compatible with the AWT's TextField used with setEchoChar. If you use the JPasswordField,the default echo character is an asterisk '*', but you can change it toany character of your choice. Again, if you set the echo character tozero, 0, it means that characters will be displayed asthey are typed and no masking will be performed. Figure 2 shows a Swinglogin dialog box where the echo character is being set to a hash sign, # using the following snippet of code:
Unlike AWT/Swing, there are no special APIs for masking command-lineinput in Java. This is a feature that has been asked for by manydevelopers. It is useful if you wish to provide a login screen forcommand-line text-based Java applications as well as server-side Javaapplications. One way to provide for such a feature is to use JavaNative Interface (JNI). This might be difficult for some Javadevelopers who do not know C/C++, or wish to keep to 100% pure Javacode.
Here I provide a solution to this problem. In the earlier version ofthis article, a UNIX-like approach to login screens, where the passwordis not echoed on the screen at all, was used. This is done by having aseparate thread that attempts to erase characters echoed to the consoleby re-writing and printing the password prompt. The code featured inthat article can still be downloaded from the forums along with code for improvements.
One of the most asked-for features, however, was replacing the echoedcharacters with asterisks "*". Therefore, this article starts byproviding a simple solution for password masking, followed by animproved, more reliable, and secure code.
This solution uses a separate thread to erase the echoed charactersas they are being entered, and replaces them with asterisks. This isdone using the EraserThread class, which is shown in Code Sample 1.
The EraserThread class is used by the PasswordField class, which is shown in Code Sample 2. This class prompts the user for a password and an instance of EraserThread attempts to mask the input with "*". Note that initially a asterisk (*) will be displayed.
As an example of how to use the PasswordField class, consider the application, TestApp,shown in Sample Code 3. This application displays a prompt and waitsfor the user to enter a password. The entry is of course masked byasterisks (*).
The above simple solution suffers from one main drawback: strings should not be used for storing sensitive information such as passwords!. In the rest of the article, an improved solution is shown.
While it may seem logical to collect and store the password using Strings, they are not suitable for storing sensitive information such as passwords. This is because objects of type String are immutable -- the contents of the string cannot be changed or overwritten after use. An array of chars should be used instead. The revised PasswordField shown in Code Sample 5 has been adapted from Using Password-Based Encryption.
This article presented an overview of password masking in Java. Itdemonstrated how easy it is to mask passwords in AWT/Swingapplications, and provided a reusable pure Java solution forcommand-line text-based password masking.
Feel free to reuse, improve, and adapt the code in this article foryour applications. You can enhance it by adding methods for passwordconstraints. As an exercise, you may wish to enhance the code presentedso that a password can be of a certain length, and so that somecharacters, such as a space for example, may not be allowed in apassword.
For me, some of this is pretty easy. I asked my teacher what would be best used for this: a char[] element, or a string element. She said string would be easier. How would I do that? What would you do, if you had a choice between either one of them. And could I convert a char[] element to a string element. Also, how would I check to see if certain characters are in the password, of which is allowed, and what is not? Here's my code:
The JPasswordField class, a subclass of JTextField, provides specialized text fields for password entry. For security reasons, a password field does not show the characters that the user types. Instead, the field displays a character different from the one typed, such as an asterisk '*'. As another security precaution, a password field stores its value as an array of characters, rather than as a string. Like an ordinary text field, a password field fires an action event when the user indicates that text entry is complete, for example by pressing the Enter button.
The password is "bugaboo". The password "bugaboo" is an example only. Use secure authentication methods in production systems. You can find the entire code for this program in PasswordDemo.java. Here is the code that creates and sets up the password field:
The argument passed into the JPasswordField constructor indicates the preferred size of the field, which is at least 10 columns wide in this case. By default a password field displays a dot for each character typed. If you want to change the echo character, call the setEchoChar method. The code then adds an action listener to the password field, which checks the value typed in by the user. Here is the implementation of the action listener's actionPerformed method:
A program that uses a password field typically validates the password before completing any actions that require the password. This program calls a private method, isPasswordCorrect, that compares the value returned by the getPassword method to a value stored in a character array. Here is its code:
PasswordDemo is the Tutorial's only example that uses a JPasswordField object. However, the Tutorial has many examples that use JTextField objects, whose API is inherited by JPasswordField. See Examples That Use Text Fields for further information.
We are going to have a Java Key Store which will store certificates & public/private keys. This keystore will be protected with the password. However, access to the keystore is only from the program. There is no way of providing input as it is only based on api access.
If you hope to keep the private keys out of the hands of whoever runs your program, then it will not work. Secrets embedded in code do not resist reverse engineering (especially when using Java, which is quite easy to reverse-engineer).
Though you do not give any detail about your situation (you just say "Java" and "the program"), I can give the following generic advice: arrange for your private key to be user-specific, and such that it is the user's best interest that the private key remains private. In that case, the user will collaborate to the key security. You may then store the private key (or a password which unlocks the private key) in the Java preferences.
Of these the first is the most common and often the password is 'password' or 'changeit' etc. The second option might seem better at first glance but it's hard to explain how exactly. The last option is probably the only one that has a hope of doing anything meaningful. I know of vendor solutions that do this kind of thing and claim to improve security.
The fundamental issue here is that if an attacker is on the host with enough access to see the application space, there's really nothing you can do to keep them from getting this password. At some point it must be in memory in the clear.
As I see it, the password on the keystore protects it mainly in situation that the keystore itself has been retrieved from the machine without actually having access to that machine directly. With that file, an attacker can hammer it at will to get the secrets out of it. If you don't have a strong password on it, game over. If the attacker can pull that file, then they likely can pull other files that the password could be stored in. This puts options 1 and 2 in doubt.
As far as the 3rd option goes, the problem now moves to how you authenticate the clients in order to retrieve the password. I know there are a number of schemes for doing this such as depending on the host/network and using signatures on the binaries. You could have an entire discussion just on how to do this and what level of protection it brings.
I am in the process of finishing up a Java application that will run a Grizzly web/REST server. The entire application will be deployed as a VM image product that people can purchase in the Microsoft Azure cloud.
In my situation I want the customer to be able to run my product's web server on the domain name of their choice. This requires that the customer go through the process of acquiring a domain name and the associated keys. Those keys will be installed into a key/trust store located on the VM where the web server will be running. My application allows the user to provide the keystore and truststore file paths and passwords three different ways:
3a8082e126