30

我正在使用以下方法从 nodejs 中的加密库创建一个加盐和散列的密码:

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

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

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

此外,对于存储,我已经看到将盐、长度、迭代和 derviedkey 存储在同一列中的示例。我正在使用一个将 4 分开的示例::,即:

salt::derivedKey::keyLength::iterations

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

4

2 回答 2

35

1.随机字节大小

盐应该至少和你的散列函数大小一样,所以sha256你应该至少使用 32 个字节。Node.js Crypto 的pbkdf2uses SHA1,所以 20 字节应该是最小的。但是,您应该使用的最少是64 位(8 字节),如 #3 中所述。(来源:https ://crackstation.net/hashing-security.htm )。

2. PBKDF2 迭代次数

请参阅此问题进行精彩讨论。我从中得出10.000 范围就足够了,不会影响性能,但这取决于硬件/性能。

3. PBKDF2 长度

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

4.如何存储变量

在上面的所有链接(尤其是第一个)中讨论过,盐应该与密码一起保存(但永远不要在其他地方重复使用),通常是首先将其附加到结果字符串 (salt:hash) 或另一个数据库列中。

至于其他变量,它们的知识对于破坏安全性并不重要(如Kerckhoffs 原则中所述,因此您可以在任何地方安全地对其进行参数化。通过将它们与“::”分隔的方式很好,但您可以节省额外的费用信息. Crackstation 的代码只保存"algorithm:iterations:salt:hash",所以在你的情况下,"salt::derivedKey::iterations"这就是你所需要的。

于 2013-10-22T19:12:44.663 回答
3

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

对派生密钥使用 64 字节是可以接受的,但单独使用 salt 就过分了。

于 2014-04-02T15:47:20.733 回答