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(passwor
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.
Fernando is mostly correct, but beware that #3 is mis-sourced. The recommended salt length is 64 bits, not bytes.
Using 64 bytes for the derived key is acceptable, but would be overkill for the salt alone.