I am using the following methods to create a salted and hashed password from the crypto lib in nodejs:
crypto.randomBytes(size, [callback]) crypto.pbkdf2(password, salt, iterations, keylen, callback)
For the randomBytes call (creating the SALT) what size should I use? I have heard 128-bit salts, maybe up to 256-bit. It looks like this function uses a size in bytes so can I assume a size of 32 (256 bits) is sufficient?
For the pbkdf2 call, what is a good number of iterations and what is a good length for the key (keylen)?
Also, for storage I have seen examples of storing the salt, length, iterations and derviedkey in the same column. I am using an example which separates the 4 by ::
, i.e.:
salt::derivedKey::keyLength::iterations
Doing this, I can then separate on ::
to get the 4 values, so I can generate a derived key based on a provided password to see if it matches. Is this the correct way to store this? Or should I be a little more "deceptive" in combining these values?
PBKDF2 applies a pseudorandom function, such as hash-based message authentication code (HMAC), to the input password or passphrase along with a salt value and repeats the process many times to produce a derived key, which can then be used as a cryptographic key in subsequent operations.
PBKDF2 is recommended by NIST and has FIPS-140 validated implementations. So, it should be the preferred algorithm when these are required. PBKDF2 requires that you select an internal hashing algorithm such as an HMAC or a variety of other hashing algorithms. HMAC-SHA-256 is widely supported and is recommended by NIST.
When to Use PBKDF2? Today PBKDF2 is considered old-fashioned and less secure than modern KDF functions, so it is recommended to use Bcrypt, Scrypt or Argon2 instead.
It is impossible to decrypt it.
1. Random bytes size:
Salts should be at least the same size as your hash function, so for sha256
you should use at least 32 bytes. Node.js Crypto's pbkdf2
uses SHA1
, so 20 bytes should be the minimum. However, the least you should use is 64 bits (8 bytes), as explained in #3. (Source: https://crackstation.net/hashing-security.htm).
2. PBKDF2 number of iterations:
See this question for a great discussion. I took from it that 10.000 range is sufficient without impact performance, but this is hardware/performance dependant.
3. PBKDF2 length:
See this other discussion about key lengths. The parameter is again the hashing function used, in your case SHA-1, so 20 bytes is the correct value. Since PBKDF2's Standard recommends salts of at least 64 bits, it's a waste to generate keys smaller than your input, so use at least 8 bytes. Do not use output length of greater than 20, as it provides no additional security, but doubles computation time for each multiple of 20.
4. How to store variables:
Discussed in all the links above (especially the first), salts should be saved along passwords (but never reused elsewhere), usually by appending it first in the resulting string (salt:hash), or in another database column.
As far as other variables, their knowledge is not critical for breaching security (as stated in Kerckhoffs's Principle, so you could parametrize it safely anywhere. Your way of doing it by separating them with "::" is fine, but you are saving extra information. Crackstation's codes only save "algorithm:iterations:salt:hash"
, so in your case, "salt::derivedKey::iterations"
is all you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With