4

I'm using KeyDerivation.Pbkdf2 to generate password hashes, and I was wondering what the general advice is regarding the salt length compared to the overall hash length that Pbkdf2 outputs.

In the implementation below, I'm using HMACSHA512, and assume that the salt is 512 bits, and that the hashBitLength is also 512 bits.

KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA512, iterationCount, hashBitLength / 8);

I've seen an example which uses HMACSHA256, but it has the salt set to 128 bits and the overall hash bit length to 256. Why would this approach be taken?

I've read that 512 bits is probably overkill, but in terms of storage, it doesn't concern me (I'm not sure how performance is impacted though, I haven't measured that).

Should the salt be the same length as the overall resulting hash. Should it be half? Or should it be anything above a certain threshold and below the overall length?

My gut says the way I'm doing it is correct (Aside from perhaps the 512 bit) as I suspect I'm getting maximum entropy, but I'm no cryptographer.

Could someone please clarify this for me?

Steviebob
  • 1,705
  • 2
  • 23
  • 36

1 Answers1

5

It really does not need to be that big, but let's understand why. The purpose of the salt is:

  1. If two people have the same passwords, then the 'hashed' result should not be the same.
  2. Prevent rainbow table attacks.

The first point can be accomplished by simply using a counter -- at least that prevents duplicates from your own database, but it might not prevent a hash of the password in your database from being the same as the hash of the same password in somebody else's database. That brings us to the second point.

If one simply used a counter starting from zero, then one could construct a rainbow table based upon it. The larger the salt, the more enormous that rainbow table would have to be to have a chance at being effective. These tables grow exponentially with the salt size, so your salt really does not have to be that big to rule out this attack.

It's hard to point out exactly a minimum size, but I can assure you that 128-bits is more than enough. I personally, as a security code auditor, would certainly not raise an issue with a salt as little as 64-bits.

One of the big problems with security advice on this topic is that nobody has ever analysed it -- instead you just get blind recommendations from people who claim to be experts. I wrote a paper on password processing making exactly this point. Specifically see section 3 for my rant about salt.

Remark: to rule out rainbow tables altogether, don't use a counter. Instead, choose your salts 'large enough' (as above) and in an unpredictable way.

TheGreatContini
  • 6,429
  • 2
  • 27
  • 37
  • 1
    Thanks for the link to your paper, there's a lot to read in there. There's a few bits that I still need answers to: 1)Should the salt be the same length as the hash? i.e. if I'm using HMAC512, should the salt be 512 bits? I've seen some sources say than the salt and the hashing algorithm are unrelated and others say they should be the same length. 2) Does a longer salt not make an attack more computationally expensive? Or is it just uniqueness that counts, not salt length (e.g. a 256 bit salt is as secure as a 4096 salt?) – Steviebob Apr 06 '17 at 21:36
  • 2
    @Steviebob: 1) No, there is no relation between salt length and hash. Actually just found yesterday that NIST is now saying that the salt only has to be 32-bits -- see [bottom of Section 5.1.1.2](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5). Those who claim that it needs to be the same length as the hash do not know what they are talking about, as evidence by their lack of justification of the claim. 2) The salt does not make anything computationally more expensive. It is used for uniqueness, preventing both duplicate outputs and rainbow attacks. – TheGreatContini Apr 06 '17 at 21:41