Why are PBKDF2-SHA256 and PBKDF2_SHA256 different in 389-ds?

In a mailing list discussion recently it came up about what password hash format should you use in 389-ds. Confusingly we have two PBKDF2 SHA256 implementations, which has a bit of history.

Too Lazy, Didn’t Read

Use PBKDF2-SHA256. (hyphen, not underscore).

What’s PBKDF2 anyway?

Passwords are a shared-knowledge secret, so knowledge of the password allows you to authenticate as the person. When we store that secret, we don’t want it stored in a form where a person can steal and use it. This is why we don’t store passwords cleartext - A rogue admin or a database breach would leak your passwords (and people do love to re-use their passwords over many websites …)

Because of this authentication experts recommend hashing your password. A one-way hash function given an input, will always produce the same output, but given the hash output, you can not derive the input.

However, this also isn’t the full story. Simply hashing your password isn’t enough because people have found many other attacks. These include things like rainbow tables which are a compressed and precomputed “lookup” of hash outputs to their inputs. You can also bruteforce dictionaries of common passwords to see if they match. All of these processes for an attacker use their CPU to generate these tables or bruteforce the passwords.

Most hashes though are designed to be fast and in many cases your CPU has hardware to accelerate and speed these up. All this does is mean that if you use a verification hash for storing passwords then an attacker just can attack your stored passwords even faster.

To combat this, what authentication experts truly recommend is key derivation functions. A key derivation function is similar to a hash where an input always yields the same output, but a KDF also intends to be resource consuming. This can be ram or cpu time for example. The intent is that an attacker bruteforcing your KDF hashed passwords should have to expend a large amount of CPU time and resources, while also producing far fewer results.

Conclusion

Use PBKDF2-SHA256.

  • It’s written in Rust.
  • It meets NIST SP800-63b recommendations.