10

We hesitated between BCrypt and PBKDF2 for password hashing. In many forums and blogs people say something like "In their Special Publication SP 800-132 NIST basically recommends using PBKDF2 for password hashing."

This may be a very important argument for our client (they adore standards). But I still cannot read this recommendation in plain text... So I can't claim it comfortably. In short NIST more or less say:

The derived keying material is called a Master Key (MK), denoted as mk. The MK is used either 1) to generate one or more Data Protection Keys (DPKs) to protect data, or 2) to generate an intermediate key to protect one or more existing DPKs or generated from the MK using an approved Key Derivation Function (KDF) as defined in [2]. The MK shall not be used for other purposes.

Is there such a recommendation or this is just a myth?

Andrei Botalov
  • 5,317
  • 10
  • 46
  • 73
Lachezar Balev
  • 537
  • 1
  • 3
  • 10
  • 3
    The NIST paper is related to algorithms for derivation of a key from a password. You only refer to "password hashing" which is not the same thing. Can you elaborate on the purpose for which you are hashing passwords? – David M May 17 '12 at 14:33
  • We store password hashes in order to authenticate users later when they log in :-) – Lachezar Balev May 17 '12 at 18:06
  • 3
    lol, only if theyve already cracked it ;-) – Alex May 17 '12 at 22:57

3 Answers3

12

The recommendation is for PBKDF2 to be used as an algorithm for generating a cryptographic key from a password, not for hashing a password for safe storage for authentication purposes. (I trust you're salting as well?) So the answer is no, for your use case there is no such recommendation. This doesn't mean it's not suitable, but there isn't a NIST recommendation to cite.

David M
  • 244
  • 2
  • 5
  • 3
    ***"What's wrong with one of the SHA-2 functions?"*** Nothing, but `bcrypt` is better because it already has single-use salt and repetition built in / less room for error. Additionally, it is more resistant to specialized hardware (GPUs) because of the additional RAM requirement. – 700 Software May 17 '12 at 21:43
  • 4
    We are salting, of course - there is no PBKDF2 without salt. The wrong thing about SHA-2 is that they are very fast and general purpose. While bcrypt and PBKDF2 are designed to be slow. And their slowness is adjustable to follow the hardware advancements. Since many people use PBKDF2 for password hashing (including stackexhange!) we will maybe stick to it. Plus there is built in support in Java while there is no such for bcrypt. But you are right... there is no such a recommendation from NIST. What I would say now is that "NIST favors PBBKDF2" :D. – Lachezar Balev May 18 '12 at 06:21
  • 2
    SHA-2 is obviously wrong for hashing a password for safe storage for authentication purposes. PBKDF2 is certainly much better in this scenario, but I'm not aware of an official NIST recommendation for this scenario. – CodesInChaos May 18 '12 at 13:42
  • @lucho, ***"slowness is adjustable to follow the hardware advancements"*** Actually you could also obtain adjustable slowness on `SHA` using repetition, though I would not recommend it (room for error, and yes, general purpose), it can be made to be nearly as effective. – 700 Software May 18 '12 at 14:38
  • PBKDF2 is basically just a small layer of repitition on top of a Hash. Each iteration executes 3 Hashes or if optimized for Merkel-Damgard one compression function per iteration plus two precomputed states. – eckes Mar 19 '17 at 11:50
9

I think you are looking for this:

Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks. Secrets SHALL be hashed with a salt value using an approved hash function such as PBKDF2 as described in [SP800-132]. The salt value SHALL be a 32 bit (or longer) random value generated by an approved random bit generator and is stored along with the hash result. At least 10,000 iterations of the hash function SHOULD be performed. A keyed hash function (e.g., HMAC), with the key stored separately from the hashed authenticators (e.g., in a hardware security module) SHOULD be used to further resist dictionary attacks against the stored hashed authenticators.

GustavoTM
  • 191
  • 1
  • 2
  • Using PBKDF2 for password hashing is a trend that replaces SHA-256 in new applications, but older apps will continue using SHA. I think, in both cases doing hashing right is important and is a common mistake, e.g. using the same salt for all users, or not having enough entropy in a salt. – Oleg Gryb Jan 07 '17 at 23:39
3

While NIST SP 800-132 is not specifically about password hashing, and especially not about passwords for authentication there is a strong recommendation to use PBKDF2 especially because of its brute-force resistence.

The upcoming NIST SP 800-63B draft (Digital Identity Guidelines Authentication and Lifecycle Management) however mentiones PBKDF2 explicit, but it also askes for a HMAC based pepper:

Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks. Secrets SHALL be hashed with a salt value using an approved hash function such as PBKDF2 as described in [SP 800-­132]. The salt value SHALL be a 32­bit or longer random value generated by an approved random bit generator and stored along with the hash result. At least 10,000 iterations of the hash function SHOULD be performed. A keyed hash function (e.g., HMAC [FIPS198­1]), with the key stored separately from the hashed authenticators (e.g., in a hardware security module) SHOULD be used to further resist dictionary attacks against the stored hashed authenticators.

There is a lot to argue about this, but in any case it asks for "approved hash function" which rules out scrypt (partially as it intentionally uses a PBKDF2 step) and bcrypt. And I love the fact it calls out for separate storage of a pepper. This is why I revived my attempt to define a common PBKDF2 format: https://github.com/ecki/habibi-passwordhash

eckes
  • 962
  • 8
  • 19
  • 1
    That 10,000 iteration number should be based on the amount of time you're willing to wait during legitimate auth flows. Figure like 500ms of processing time in your environment. So as systems get faster, that number should go up, but you need to have agility built in at that point. 10,000 is probably an absolute minimum, but if you actually implement this, do testing first. – Scovetta Mar 19 '17 at 15:17