As mentioned in this wonderful link, the way to get a PBKDF2 Hash of a user given password given
- a password (of course),
- a salt (generated Cryptographically Secure Random Number Generator.
- iteration count (chosen high enough to be secure while balancing your application's usability tolerance)
- Hash size (length of the hash to be computed)
/**
* Computes the PBKDF2 hash of a password.
*
* @param password the password to hash.
* @param salt the salt
* @param iterations the iteration count (slowness factor)
* @param bytes the length of the hash to compute in bytes
* @return the PBDKF2 hash of the password
*/
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
throws NoSuchAlgorithmException, InvalidKeySpecException
{
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
return skf.generateSecret(spec).getEncoded();
}
Now my question is :
How should the Keyed hashing for the password be implemented ?
Based on my reading, this is my line of thinking. Please validate.
Keep the salt argument to the method pbkdf2 (in the code snippet above) secret (obtain it from a highly secure HSM as opposed to storing it in the database alongside the password hash when needed).
Since the salt is meant to be random (to protect them from the rainbow tables / dictionary attacks), the salt provided to the pbkdf2 should be a concatenation of the key and a random bytes generated from a CSPRNG.
[salt] = [secret key] + [random bytes from a CSPRNG]
Finally, I will dare to ask a silly question (will dare to ask since high iteration count is posing a serious usability issue since we need to authenticate for 90% of the use cases in our application)
Can we reduce the iteration count OR do without it since we have added an additional layer of security through the Keyed hashing ?
P.S: I am aware of the value that slow hashing algorithms add by reducing the possibility of passwords getting compromised through brute force attacks. Just want the experts to comment on the security value addition through Keyed Hashing VS having a Slow Hashing algorithm with non-secret salt.