使用pbkdf2进行SALT和HASH

时间:2013-06-20 15:45:46

标签: node.js passwords pbkdf2 password-storage

我使用以下方法从nodejs中的crypto lib创建salted和散列密码:

crypto.randomBytes(size, [callback])
crypto.pbkdf2(password, salt, iterations, keylen, callback)

对于randomBytes调用(创建SALT)我应该使用什么尺寸?我听过128位盐,可能高达256位。看起来这个函数使用的是字节大小,所以我可以假设32(256位)的大小就足够了吗?

对于pbkdf2调用,什么是好的迭代次数以及密钥(keylen)的长度是多少?

另外,对于存储,我已经看到了在同一列中存储salt,length,iterations和derviedkey的示例。我正在使用一个例子,用::分隔4,即:

salt::derivedKey::keyLength::iterations

执行此操作后,我可以在::上分隔以获取4个值,因此我可以根据提供的密码生成派生密钥,以查看它是否匹配。这是存储它的正确方法吗?或者,在结合这些价值观时,我是否应该更具“欺骗性”?

2 个答案:

答案 0 :(得分:27)

<强> 1。随机字节大小:

Salt的大小应至少与哈希函数的大小相同,因此对于sha256,您应该使用至少32个字节。 Node.js Crypto的pbkdf2使用SHA1,所以20个字节应该是最小的。但是,您应该使用的最少的是 64位(8字节),如#3中所述。 (来源:https://crackstation.net/hashing-security.htm)。

<强> 2。 PBKDF2迭代次数:

请参阅this question进行精彩讨论。我从中得出 10.000范围就足够了,没有影响性能,但这取决于硬件/性能。

第3。 PBKDF2长度

有关密钥长度,请参阅this other discussion。该参数再次是使用的散列函数,在您的情况下为SHA-1,因此20个字节是正确的值。由于PBKDF2's Standard建议使用至少 64位的盐,因此生成小于输入的密钥是浪费,因此至少使用 8字节。不要使用大于20的输出长度,因为它不提供额外的安全性,但每20的倍数计算时间加倍。

<强> 4。如何存储变量:

在上面的所有链接中讨论(尤其是the first),盐应该沿着密码保存(但从不在别处重复使用),通常是先将其附加到结果字符串(salt:hash)中,或者放在另一个数据库中柱。

就其他变量而言,他们的知识对于破坏安全性并不重要(如Kerckhoffs's Principle中所述,因此您可以在任何地方安全地进行参数化。通过将它们与“::”分开来实现它的方式很好,但是您要保存额外的信息Crackstation's codes仅保存"algorithm:iterations:salt:hash",因此在您的情况下,您只需要 "salt::derivedKey::iterations"

答案 1 :(得分:3)

费尔南多大多是正确的,但要注意#3是错误的来源。建议的盐长度为64 ,而不是字节。

对于派生密钥使用64个字节是可以接受的,但对于单独的盐来说是过度的。