Insecure hash algorithm usage with passwords detectedJAVA-S1006
The MD* family of hashing algorithms (MD2, MD4 and MD5), as well as SHA-1 are cryptographically insecure and are very susceptible to collision attacks. These algorithms must not be used to hash passwords or cryptographically significant values.
MD5 in particular suffers from a number of collision attacks, which render it unsuitable as a password hash function:
... The security of the MD5 hash function is severely compromised. A collision attack exists that can find collisions within seconds on a computer with a 2.6 GHz Pentium 4 processor (complexity of 224.1).Further, there is also a chosen-prefix collision attack that can produce a collision for two inputs with specified prefixes within hours, using off-the-shelf computing hardware (complexity 239). ...
- Wikipedia: MD5 - Security
Similarly, SHA-1 is not safe for use as a password or signature verification algorithm.
SHA-1 for digital signature generation: SHA-1 may only be used for digital signature generation where specifically allowed by NIST protocol-specific guidance. For all other applications, SHA-1 shall not be used for digital signature generation. SHA-1 for digital signature verification: For digital signature verification, SHA-1 is allowed for legacy-use. ...SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256: The use of these hash functions is acceptable for all hash function applications.
- NIST: Transitioning the Use of Cryptographic Algorithms and Key Lengths (p15)
Passwords must be hashed only using specific password hashing algorithms such as PBKDF2. This is because such algorithms are tailored to the specific use case of ensuring an attacker cannot easily perform a brute force attack to figure out the password:
... The main idea of a PBKDF is to slow dictionary or brute force attacks on the passwords by increasing the time needed to test each password. An attacker with a list of likely passwords can evaluate the PBKDF using the known iteration counter and the salt. Since an attacker has to spend a significant amount of computing time for each try, it becomes harder to apply the dictionary or brute force attacks. ...
- NIST: Recommendation for Password Based Key Derivation, (p12)
Bad Practice
MessageDigest md = MessageDigest.getInstance("SHA1");
String password = "secret";
Byte[] output = md.digest(pasword.getBytes());
Recommended
In general, there are a number of choices for hash functions that do not have such glaring collision vulnerabilities:
... SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256: The use of these hash functions is acceptable for all hash function applications. ...
- NIST: Transitioning the Use of Cryptographic Algorithms and Key Lengths (p15)
PBKDF2 is the recommended algorithm to use when hashing passwords.
Here is an example of its usage, in Java 8 and above:
public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 4096, 256 * 8);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
return f.generateSecret(spec).getEncoded();
}
If the javax.crypto package cannot be used, or you are using an older version of Java, you could use the BouncyCastle library:
public static byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
gen.init(password.getBytes("UTF-8"), salt.getBytes(), 4096);
return ((KeyParameter) gen.generateDerivedParameters(256)).getKey();
}
References
- FindSecBugs - WEAK_MESSAGE_DIGEST_MD5
- Wikipedia - MD5 security
- NIST - Transitioning the Use of Cryptographic Algorithms and Key Lengths (PDF)
- NIST - Recommendation for Password Based Key Derivation (PDF)
- Google online security blog - Gradually Sunsetting SHA-1
- StackOverFlow - Reliable implementation of PBKDF2-HMAC-SHA256 for JAVA
- CWE-310 - Cryptographic Issues
- CWE-327 - Use of a broken or risky hash algorithm
- OWASP Top Ten (2021) - Category A02 - Cryptographic Failures