使用 pbkdf2 的 SALT 和 HASH

Posted

技术标签:

【中文标题】使用 pbkdf2 的 SALT 和 HASH【英文标题】:SALT and HASH using pbkdf2 【发布时间】:2013-06-17 13:44:22 【问题描述】:

我正在使用以下方法从 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 个值,因此我可以根据提供的密码生成派生密钥以查看它是否匹配。这是存储它的正确方法吗?还是我应该在结合这些价值观时更加“欺骗”一些?

【问题讨论】:

【参考方案1】:

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" 就是你所需要的。

【讨论】:

“由于 PBKDF2 的标准建议使用至少 64 位的盐,生成小于输入的密钥是一种浪费,因此至少使用 64 字节。” salt 输入只需 8 个字节长(64 ),这里有错字吗? @StrangeWill 是的,请参阅迈克尔的评论。但我正在编辑我的答案以反映这一点。 实际上,由于我的答案很旧并且已经被接受,因此我宁愿不要更改太多。但是 #1 和 #3 的粗体大小将更改为推荐的 20 字节 - PBKDF2 推荐 64 位,因此 8 字节,但盐应该至少与散列函数的大小相同,因此对于 SHA1 以防万一Node.js Crypt 是 20 个字节,SHA256 是 32 个字节。【参考方案2】:

Fernando 基本上是正确的,但要注意 #3 的来源有误。建议的盐长度是 64 ,而不是字节。

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

【讨论】:

你指出我的错误是对的。然后,我对 #3 的结论将更改为 32 字节 盐。这样做的原因来自第一篇来源文章:“一个好的经验法则是使用与散列函数的输出大小相同的盐。”因此,如果他使用 SHA-256,他的 salt 应该与输出相同(32 字节),高于建议的最小 64 位。

以上是关于使用 pbkdf2 的 SALT 和 HASH的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振(飞镖)应用程序和 PHP 网站之间使用 SALT+HASH 密码保存/检查?

使用Pbkdf2加密加密和验证使用Salt的哈希密码

如何正确存储 PBKDF2 密码哈希

使用PBKDF2密钥派生来正确创建用户可读的salt with dry-crypto

常见用户密码加密方式之特殊的单向HASH算法

使用 HMAC SHA-1 的 PBKDF2 如何返回超过 20 个字节?