I'm working on a Java authentication subsystem that specs the storage of passwords in the DB as PBKDF2-generated hashes, and I'm now trying to decide whether I should use SHA1 or SHA512 as PFR. I'm under the impression that the consensus is that SHA1 has some theoretical weaknesses, and that SHA512 should be chosen instead. However the standard javax.crypto package does not offer a PBKDF2WithHmacSHA512 implementation, how is that so?

For reference purposes, here’s my code:

private static final int HASH_BYTE_SIZE = 64; // 512 bits
private static final int PBKDF2_ITERATIONS = 1000;      

// generate random salt
SecureRandom random = new SecureRandom();
byte salt[] = new byte[SALT_BYTE_SIZE]; // use salt size at least as long as hash

// generate Hash
PBEKeySpec spec = new PBEKeySpec(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); // this throws a NoSuchAlgorithmException if I replace with "PBKDF2WithHmacSHA512"
byte[] hash = skf.generateSecret(spec).getEncoded();

// convert hash and salt to hex and store in DB as CHAR(64)...
  • 1
    $\begingroup$ I guess you are better off using a binary field instead of hex for the salt, but if you must you should use a CHAR field of 128 bytes, not 64. Furthermore, it may be a good idea to store the iteration count as well or create a "protocol indicator" or version field so you can upgrade your security later on. $\endgroup$ – Maarten Bodewes Oct 13 '13 at 22:47
  • 1
    $\begingroup$ SHA-512 and SHA-384 (unlike SHA-1, SHA-224, and SHA-256) use 64-bit operations that reduce the margin of superiority that modern (early 2014) GPU's have over CPU's. Since an attacker is more likely to benefit from GPU's than you are, that's a good (but constant factor) reason to use PBKDF2-HMAC-SHA-512 for the same amount of CPU time you would have budgeted to PBKDF2-HMAC-SHA-1. $\endgroup$ – Anti-weakpasswords Feb 25 '14 at 5:41
  • $\begingroup$ See also my answer to a similar question on StackOverflow. $\endgroup$ – hobbs Sep 10 '15 at 6:29

Hash algorithm strength is important, but it is not so important in key derivation functions. It is unlikely that even if SHA-1 is broken that it would influence the security of PBKDF2. You are better off using SHA-1, and increase the iteration count up to a level that is tweaked for your specific configuration.

If you must, you could use Bouncy Castle to create an implementation of PBKDF2 with SHA-256. The internal security of the algorithm is not that important, if your server is relatively safe against side channel attacks (and for PBKDF2 it likely is). So using a non-certified open source solution would probably not compromise your security.

Your efforts are probably better spend elsewhere. Congratulate yourself on choosing a relatively good password based KDF, choose a 64 bit random salt and use a higher iteration count, and move on...

Note: if you want to protect against hardware accelerated attacks, you may want to consider scrypt instead of PBKDF2.

The Oracle JDK 1.8 contains PBKDF2 implementations for SHA-512 "PBKDF2WithHmacSHA512". This can be used for compatibility with other systems or for deprecating SHA-1 entirely.


Short answer: You can use SHA1 in this situation. Rather than using PBKDF2, you should consider using SCrypt or some other time-memory algorithm. You need to up your iteration count to something like 10,000,000: think Moore's law increase since 1000 was published in the spec in the late 1990s.

Long answer: The attacks against SHA1 are for collision resistance, and not for preimage or 2nd preimage resistance. See https://stackoverflow.com/questions/8860512/whats-the-difference-between-collision-resistance-and-preimage-resistance for what this means. For PBKDF2, the type of resistance which is important is the preimage and 2nd preimage resistance.

SHA1 provides 160 bits of security strength when used for preimage and 2nd preimage resistance. 160 bits of security strength is quite fine to use now and in the medium term. See http://www.keylength.com/ for thoughts on how long a certain key size / security strength can be used for.

  • $\begingroup$ Why 10 million? Moore's law would imply a factor of a few hundred, not ten thousand. (I don't necessarily disagree, but would like to see justification.) $\endgroup$ – otus Sep 8 '15 at 6:22
  • $\begingroup$ I concur. 10M iterations might be a terrible choice based on the application and infrastructure. Perhaps expand into more general advice such as "use the number of iterations such that interactive login takes 500 ms on your current infrastructure". Anything more is overkill, painful for the user, and a huge DoS vector. $\endgroup$ – rmalayter Sep 9 '15 at 1:16

...the standard javax.crypto package does not offer a PBKDF2WithHmacSHA512 implementation, how is that so?

Starting with Java8, there is support for PBKDF2With<prf> where <prf> can be any number pseudo-random functions, including HmacSHA512.

So it is now supported.

Any thoughts?

What the others have said is good advice. If for some reason you really wanted to use PBKDF2 with HmacSHA512 in standard java, you can if you switch to Java8.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.