...
An acceptable technique for limiting the exposure of passwords is the use of hash functions, which allow programs to indirectly compare an input password to the original password string without storing a cleartext or decryptable version of the password. This approach minimizes the exposure of the password without presenting any practical disadvantages.
Cryptographic Hash Functions
The value produced by a hash function is the hash value or message digest. Hash functions are computationally feasible functions whose inverses are computationally infeasible. In practice, a password can be encoded to a hash value, but decoding remains infeasible. The equality of passwords can be tested through the equality of their hash values.
...
Java's MessageDigest
class provides implementations of various cryptographic hash functions. Avoid defective functions such as the Message-Digest Algorithm (MD5). Hash functions such as Secure Hash Algorithm (SHA)-1 and SHA-2 are maintained by the National Security Agency and are currently considered safe. In practice, many applications use SHA-256 because this hash function has reasonable performance while still being considered secure.
Noncompliant Code Example
This noncompliant code example encrypts and decrypts the password stored in password.bin
using a symmetric key algorithm:
...
An attacker could potentially decrypt this file to discover the password, particularly when the attacker has knowledge of the key and encryption scheme used by the program. Passwords should be protected even from system administrators and privileged users. Consequently, using encryption is only partly effective in mitigating password disclosure threats.
Noncompliant Code Example
This noncompliant code example uses the SHA-256
hash function through the MessageDigest
class to compare hash values instead of cleartext strings, but it uses a String
to store the password:
...
Although this approach solves the decryption problem from the previous noncompliant code example, this program may inadvertently store the passwords as cleartext in memory. Java String
objects are immutable and can be copied and internally stored by the Java Virtual Machine. Consequently, Java lacks a mechanism to securely erase a password once it has been stored in a String
. See MSC59-J. Limit the lifetime of sensitive data for more information.
Compliant Solution
This compliant solution addresses the problems from the previous noncompliant code example by using a byte
array to store the password:
...
In both the setPassword()
and checkPassword()
methods, the cleartext representation of the password is erased immediately after it is converted into a hash value. Consequently, attackers must work harder to retrieve the cleartext password after the erasure. Providing guaranteed erasure is extremely challenging, is likely to be platform specific, and may even be impossible because of copying garbage collectors, dynamic paging, and other platform features that operate below the level of the Java language.
Applicability
Passwords stored without a secure hash are exposed to malicious users. Violations of this guideline generally have a clear exploit associated with them.
Applications such as password managers may need to retrieve the original password to enter it into a third-party application. This is permitted even though it violates this guideline. The password manager is accessed by a single user and always has the user's permission to store his or her passwords and to display those passwords on command. Consequently, the limiting factor to safety and security is the user's competence rather than the program's operation.
Bibliography
[API 2013] | Class MessageDigest Class String |
[Hirondelle 2013] | Passwords Never Clear in Text |
[OWASP 2012] | "Why Add Salt?" |
[Paar 2010] | Chapter 11, "Hash Functions" |
...