Reputation: 9635
I need to hash a message with random salt and iteration count.
Here is the way I used (Way-1)
public static void main(String[] args) {
byte[] message;
byte[] randomSalt;
int iterations = 1000;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(message);
for (int i = 0; i < iterations; i++) {
// randomSalt used multi-times
hash = digest.digest(ArrayUtils.appendArrays(randomSalt, hash));
}
// Final result: randomSalt + hash
}
However, I found another way people used (Way-2)
public static void main(String[] args) {
byte[] message;
byte[] randomSalt;
int iterations = 1000;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
// Use randomSalt Once
digest.update(randomSalt);
byte[] hash = digest.digest(message);
for (int i = 0; i < iterations; i++) {
// randomSalt Are Not used here
hash = digest.digest(hash);
}
// Final result: randomSalt + hash
}
Of course, two way produce different outputs.
The mainly different between Way-1 and Way-2 is in Way-1, salt is used Multi-times.
Question: Which way do you recommend? Thanks!
Upvotes: 0
Views: 2626
Reputation: 61892
None of them.
If you're hashing passwords to produce an encryption key, then you should use available standardized schemes such as PBKDF2, bcrypt, scrypt or Argon2. They are specifically designed for this purpose. For example, scrypt and Argon2 will use a high amount of memory so that cracking speedup through ASICs cannot be achieved.
If you're hashing a message for authentication purposes as in MAC, then you only need to hash twice. HMAC is a standardized scheme in that regard which for example prevents length-extension attacks that would have been possible with the underlying hash function alone. Having multiple iterations doesn't add security unless the HMAC key is of low entropy (such as a password), in which case, you would need to derive a proper key with the first suggestion of using a password-based key derivation function.
If you just need an integrity checking value, then doing multiple iterations is useless and a single hash of the message would suffice (it doesn't even have to be salted). Integrity doesn't have a security purpose and only protects against accidental manipulation. Multiple iterations on the other hand are usually used to slow down some operation which is not what you want with integrity checking. If you need to detect malicious manipulation, then you need to use a MAC, which is nothing more than a keyed-hash in case of HMAC.
If you need a hash of a message for signing, then multiple iterations also don't provide additional security. A hash for signing is only used to reduce the size of the message to sign. The actual signature security is provided by the asymmetric algorithm and not the hashing algorithm, so multiple iterations don't add additional security here. If the signature algorithm is broken, then an attacker can simply create a hash of the manipulated message and sign it.
Those are only some of the uses of hash functions, but they are the most popular. Iterated hash functions are only useful in 1 of the 4 cases.
Upvotes: 3