I know that .NET's Rfc2898DeriveBytes requires at least 8 bytes of salt, but how many bytes are ideal?

When a user is created, or changes their password, my server stores a new random salt for that user, and a "hash", which is really just some number of bytes from Rfc2898DeriveBytes (ed: .NET's implementation of PBKDF2), using the user's password and the salt, and 5000 iterations.

My client app connects to the server via SSL, sends the user's user name, the server sends the salt for that user, the client calls Rfc2898DeriveBytes with the user's password and the salt, and sends that "hash" to the server for authentication. If the server receives an invalid user name, it returns a random salt, so that the client doesn't know whether the user name or the password is invalid, and so some time is wasted to hamper hacking.

My understanding about salt is that it's really only intended to get different keys for the same password, which would lead me to think that 8 random bytes should suffice, but since I'm sending it over SSL, I'm wondering if a longer salt would increase security somehow.

Besides the number of salt bytes, how many "hash" bytes would be best?


1 Answer 1


Short Answer: 8 bytes are fine

Longer answer: The point of the salt in a password hash is, to prevent the precalculation of a list of hashes, usually done in the form of rainbow tables. If someone still wants to do precalculation, he will have to build one rainbow table for every single possible salt value, thus you are increasing the storage requirements of your adversary.

With a 8 byte salt, the adversary will need to build $2^{64} \approx 10^{19}$ tables. The size of those tables varies depending on the types and length of password you are trying (you can find a nice overview here), but you typically expect something in the 2-3 digit gigabyte range ($10^{11}-10^{12}$ byte). Putting this together, storing rainbow tables for 8 bytes of salt would require something in the range of $10^{30}$ bytes, which is completely impossible.

  • $\begingroup$ Thank you for your well-explained response. Do you have an opinion regarding the number of bytes to get from Rfc2898DeriveBytes for the "hash"? This is what the server will store for a user instead of their password, and what the client app will send (via SSL) for authentication. On one hand, smaller is better because that will keep messages small, but obviously, I don't want to use too few bytes. $\endgroup$
    – uncaged
    Jul 23, 2017 at 16:20
  • $\begingroup$ The larger the hash length, the smaller the possibility of a collision. You should use at least 256 bit, which will give you approximately 128 bit security. $\endgroup$
    – mat
    Jul 23, 2017 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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