In Swing, the password field has a getPassword()
(returns char[]
) method instead of the usual getText()
(returns String
) method. Similarly, I have come across a suggestion not to use String
to handle passwords.
Why does String
pose a threat to security when it comes to passwords?
It feels inconvenient to use char[]
.
Edit: Coming back to this answer after a year of security research, I realize it makes the rather unfortunate implication that you would ever actually compare plaintext passwords. Please don't. Use a secure one-way hash with a salt and a reasonable number of iterations. Consider using a library: this stuff is hard to get right!
Original answer: What about the fact that String.equals() uses short-circuit evaluation, and is therefore vulnerable to a timing attack? It may be unlikely, but you could theoretically time the password comparison in order to determine the correct sequence of characters.
Some more resources on timing attacks:
String is immutable and it goes to the string pool. Once written, it cannot be overwritten.
char[]
is an array which you should overwrite once you used the password and this is how it should be done:One scenario where the attacker could use it is a crashdump - when the JVM crashes and generates a memory dump - you will be able to see the password.
That is not necessarily a malicious external attacker. This could be a support user that has access to the server for monitoring purposes. He could peek into a crashdump and find the passwords.
While other suggestions here seem valid, there is one other good reason. With plain
String
you have much higher chances of accidentally printing the password to logs, monitors or some other insecure place.char[]
is less vulnerable.Consider this:
Prints:
Some people believe that you have to overwrite the memory used to store the password once you no longer need it. This reduces the time window an attacker has to read the password from your system and completely ignores the fact that the attacker already needs enough access to hijack the JVM memory to do this. An attacker with that much access can catch your key events making this completely useless (AFAIK, so please correct me if I am wrong).
Update
Thanks to the comments I have to update my answer. Apparently there are two cases where this can add a (very) minor security improvement as it reduces the time a password could land on the hard drive. Still I think it's overkill for most use cases.
If possible, disabling core dumps and the swap file would take care of both problems. However, they would require administrator rights and may reduce functionality (less memory to use) and pulling RAM from a running system would still be a valid concern.
Character arrays (
char[]
) can be cleared after use by setting each character to zero and Strings not. If someone can somehow see the memory image, they can see a password in plain text if Strings are used, but ifchar[]
is used, after purging data with 0's, the password is secure.The answer has already been given, but I'd like to share an issue that I discovered lately with Java standard libraries. While they take great care now of replacing password strings with
char[]
everywhere (which of course is a good thing), other security-critical data seems to be overlooked when it comes to clearing it from memory.I'm thinking of e.g. the PrivateKey class. Consider a scenario where you would load a private RSA key from a PKCS#12 file, using it to perform some operation. Now in this case, sniffing the password alone wouldn't help you much as long as physical access to the key file is properly restricted. As an attacker, you would be much better off if you obtained the key directly instead of the password. The desired information can be leaked manifold, core dumps, a debugger session or swap files are just some examples.
And as it turns out, there is nothing that lets you clear the private information of a
PrivateKey
from memory, because there's no API that lets you wipe the bytes that form the corresponding information.This is a bad situation, as this paper describes how this circumstance could be potentially exploited.
The OpenSSL library for example overwrites critical memory sections before private keys are freed. Since Java is garbage-collected, we would need explicit methods to wipe and invalidate private information for Java keys, which are to be applied immediately after using the key.