I’m looking for the proper Java algorithm for password encryption, and I found that Java SDK provides PBKDF2WithHmacSHA1, but not PBKDF2WithHmacSHA256.
I heard that HMAC-SHA256 will take more time than HMAC-SHA-1 does.
Since system resources are limited,
I’m going to apply different iteration values to make them most secure as long as service requirements can bear it.
Even with the same expected time of processes, using HMAC-SHA256 is more secure than using HMAC-SHA-1?
If so, could you describe how far using HMAC-SHA256 is secure than using HMAC-SHA-1?
Pro #1: SHA-256 is a longer hash than SHA-1 (256 bits vs. 160 bits), so the chances of finding a collision using pure brute force are much lower. Even with the iteration counts adjusted so that the time to compute a single PBKDF2 hash is the same, you will have to hash 2^96 times as many random inputs to get a match with PBKDF2-SHA-256 than with PBKDF2-SHA-1
Con #1: No one attacks password hashes using pure brute force, they use dictionary attacks, hybrid dictionary attacks, and limited-character-set attacks. All of these use a limited input space small enough that neither PBKDF2-SHA-1 nor PBKDF2-SHA-256 are likely to have any natural collisions. The limited password search space makes the size of the hash irrelevant as long as it’s “big enough”, and so the only thing affecting the difficulty of an attack is the time to compute a single PBKDF2 hash. Besides, PBKDF2 has a way of stretching the output length to be longer than the underlying hash length, so you can actually make the two have an equivalent output space.
Pro #2: SHA-1 is at least partially broken; cryptanalysis has resulted in attacks that can find collisions faster than brute force. Once an attack is found you can usually expect it to be improved upon — this means that the suitability of SHA-1 for anything that needs to be secure more than a few minutes into the future is in doubt.
Con #2: SHA-1 is “broken” in theory, but the attacks that have been found are still extremely expensive, and as far as I know they’re all birthday attacks (which don’t help you break a password database) and not pre-image attacks (which do). Furthermore, because PBKDF2 uses many iterations of the hash, combining rounds of hash output with the password over and over, it’s difficult to extend an attack on the hash into an attack on PBKDF2. It would take a very grave attack on SHA-1 to make PBKDF2-SHA-1 insecure.
Overall, I think you should prefer PBKDF2-SHA-256 on general principle, but if it’s not available, PBKDF2-SHA-1 is still widely-used and a reasonable option for medium-security password hashing at this time.