12

I use PBKDF2 with SHA-256 to store hashes of passwords. I use the following parameters:

number of iterations desired        = 1024
length of the salt in bytes         = 16
length of the derived key in bytes  = 4096 

But recently I found out that most probably the parameters are badly selected.

For example wiki page says:

standard was written in 2000, the recommended minimum number of iterations was 1000 .... As of 2005 a Kerberos standard recommended 4096 iterations

which means that most probably I have to increase this number

and

The standard recommends a salt length of at least 64 bits

Which means that my salt length is ok is too low (thanks to Neil Smithline). But when searching through the standard I was not able to find the mention about recommended salt length.

When I looked for the length of the derived key and found this nice answer:

If you use PBKDF2 for password hashing, then 12 bytes of output ought to be fine, with a non-negligible security margin

it suggested me that I took too big number which probably does not make sense.


So my question is: can anyone show good parameters (may be with some justifications/links) for this scenario of password hashing (as of 2016). Also can I guarantee that the derived key length will be always the same length as I ask?

8
  • 3
    Your salt length is 16 bytes which is 128 bits. The recommendation that you quote is 12 bytes which is 96 bits. So your salt length is fine. Commented Jan 8, 2016 at 20:39
  • 1
    Are you really storing a 4096 byte password hash?!!? That is sort of huge. Commented Jan 8, 2016 at 20:44
  • @NeilSmithline was going to (now I only work on this project). And looking at the answer I started to think that this does not make sense. Commented Jan 8, 2016 at 20:49
  • One good answer is also here: security.stackexchange.com/a/106216/78998
    – Vilican
    Commented Jan 9, 2016 at 19:33
  • 1
    Current iteration count recommendation is 100000+, quarter million for high security applications Commented Feb 21, 2016 at 9:21

3 Answers 3

25

Your starting point

PBKDF2-HMAC-SHA-256

number of iterations desired = 1024

length of the salt in bytes = 16

length of the derived key in bytes = 4096


Algorithm

Ok - PBKDF2-HMAC-SHA-256 is a solid choice, though if you're running on any modern 64-bit CPU, I would strongly recommend PBKDF2-HMAC-SHA-512 instead, because SHA-512 requires 64-bit operations that reduce the margin of a GPU based attacker's advantage, since modern GPU's don't do 64-bit as well.


Salt

16 bytes of salt is fine, as long as it is cryptographically random and is unique per password. Normal recommendations are in the 12-24 byte range, with 16 considered quite solid.


Output and Iterations

4096 bytes of output is ACTIVELY BAD! SHA-256 has a native output size of 32 bytes. PBKDF2/RFC2898 states that in this case, you'll first run 1024 iterations to get the first (leftmost) 32 bytes, then another 1024 iterations for the next 32 bytes, and so on for 128 times in total to get the full 4096 bytes of output you requested.

So, you did 131072 iterations total, and got 4096 bytes of output. The attacker is going to do 1024 iterations total, and compare their 32 bytes of output to the first (leftmost) 32 bytes of your output - if those are the same, they guessed correctly! You just gave every attacker a 128:1 advantage!

Instead, if you're happy with the speed, you should do 131072 iterations with 32 bytes of output - you will spend the SAME amount of time you are now (so it's free!), and your attackers will need to spend 128 times more time than they do now!

  • NOTE: If you move to PBKDF2-HMAC-SHA-512, you can use up to 64 bytes of output, and each iteration will take slightly longer.

Never get more output for password hashing than the native output of your hash function, i.e. 20 bytes for SHA-1, 32 for SHA-256, 64 for SHA-512. You can optionally store less, but it doesn't save you any computations. I would recommend storing at least 28 bytes of output (224 bits, which is twice 112 bits, the nominal security of 3DES).

Note that output length values are pure binary output - BEFORE you BASE64 or hexify them, if you do (personally, I'd store the raw binary - it uses less space, and requires one less conversion).

1
  • You can use the 32 bytes output with HKDF extract with salt to derive more keys.
    – kelalaka
    Commented Feb 12, 2020 at 8:27
9
  1. 8 bytes salt is fine, because that is globally unique when randomly generated, and that's the purpose of a salt: uniqueness. Too big is not an issue so estimating on the high side is fine, except you waste a little bit of storage.

  2. 32 bytes would be good for a derived key length (most hashing algorithms will output between 16 and 64 bytes, where 64 is just overkill). Your value of 4096 is definitely overkill -- I actually hope you mistook bytes for bits there!

  3. Iterations is very simple: as many as possible on your hardware. If a login may take up to half a second, then benchmark how many iterations you can do before it passes half a second. In 2020, 400 000 is a reasonable value for a low-end server (average server CPUs can handle more iterations).

  4. SHA-256 is a good algorithm if you have to choose one. Avoid MD5, SHA-1, and anything else with known attacks. They may be secure for this purpose (even MD5), but attacks only ever get better and you might as well not use something that's already partially broken.

If you're running on an underpowered system (e.g. Raspberry Pi), you might want to consider different hardware depending on how secure things should be, or make the login take a longer time. A login is typically done only once a day or so anyway, so waiting 10 seconds might be reasonable depending on your application.

0
7

My first suggestion is to use the default password storage mechanism of your platform. Functions like PHP's password_hash take all the worry and fuss out of password storage.

Assuming that you can't do that, I recommend using bcrypt, or maybe even the newer scrypt functions. bcrypt is more difficult to crack when using parallel operations on a GPU. scrypt taxes memory as well as the CPU. This answer explains all this is great detail.

Assuming that you're stuck with pbkdf2 for whatever reason...

Salt: According to this 2013 answer by Thomas Pornin, 128 bits or 16 bytes is sufficient. The recommendations of the Crackstation is 192 bits or 24 bytes. I think anywhere in that range is safe. Personally, I would go with the 24 bytes as the salt length (assuming that you don't hang on generating random data) doesn't really contribute to the hash performance. Be sure to use a CSPRNG for generating the salt.

Password Length: Thomas Pornin's answer recommends 12 bytes, Crackstation 24. Again, I would tend to go with the larger size but think anything in that range is safe.

Iterations: The number of iterations should be as many as you can tolerate. So start testing the performance of the hashing. I've seen recommendations for 0.05-0.10 seconds but think those are just estimates. If you have computational resources to spare, perhaps you can go a bit higher (too much higher will slow authentication too much). If you're scarce on computational resources, go smaller.

Summary:

number of iterations desired        = max you can tolerate
length of the salt in bytes         = 16-24
length of the derived key in bytes  = 12-24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .