我使用以下方法从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个值,因此我可以根据提供的密码生成派生密钥,以查看它是否匹配。这是存储它的正确方法吗?或者,在结合这些价值观时,我是否应该更具“欺骗性”?
答案 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个字节是可以接受的,但对于单独的盐来说是过度的。