我正在尝试创建PBKDF2的实现来生成使用AES-256加密文件的密钥,但我对盐大小有疑问。我计划使用SHA-256并与密码连接,如果连接的位串的大小大于256位,它会有所不同,或者如果盐和密码都是256位,它会被认为更安全,使它们串联512位?
答案 0 :(得分:1)
首先,让我们备份并快速查看PBKDF2:
PBKDF2生成一个长度为所需字节数的输出。它通过计算多个“块”来生成这些字节。每个块都是所选哈希的大小。例如,如果您希望派生一个64字节长的密钥,并且希望使用产生32字节哈希的SHA-256,则将生成2个PBKDF2块。最终输出是这些块的串联。
那么如何生成每个块?
好吧,(我将在这里使用RFC命名法),块由函数F
生成。此函数接收用户密码P
,您的盐[{1}},所需的迭代计数S
以及您正在生成的块的索引c
(从一个开始)
对于第一个块,您的函数调用类似于:i
(注意我使用的是100k迭代。有关选择此值的更多信息,请参阅this post。)
回顾RFC:
F ("MySecretPassword", "random_salt", 100000, 1)
F(P, S, c, i) = U_1 \xor U_2 \xor U_3 ... U_c
U_1 = PRF(P, S || INT(i))
U_2 = PRF(P, U_1)
U_3 = PRF(P, U_2)
...
U_c = PRF(P, U_{c-1})
代表伪随机函数。对于SHA-256,应该是基于SHA-256的HMAC。该功能首先使用与块号PRF
连接的盐P
为您的密码S
生成SHA-256 HMAC。然后,函数迭代(i
次),并且XOR是先前结果的结果。每次迭代使用SHA-256 HMAC(再次)散列密码c
,但使用先前结果作为HMAC密钥。
所以 - 回到你的问题 - 因为我们正在使用HMAC,盐长度无关紧要**并且可以超过256位。当为HMAC提供一个密钥(在这种情况下,您的密码)长于哈希输出的长度时,它将对密钥进行哈希处理以获得正好256位。如果提供了一个短于256位的密钥,则将其填充以获得正好256位。从某种意义上说,这些细节对您的实现是隐藏的,所以您不必担心您将多少盐传入PBKDF2。
**嗯,在某种程度上确实重要。请参阅owlstead对另一个答案的评论。它应该足够长,以阻止彩虹表的使用。 (虽然因为PBKDF2大量应用你的哈希函数,所以长盐比传统的'直接哈希'应用程序重要。)对于我的应用程序,我使用32字节随机盐,对于我所在的每个用户帐户都是唯一的用PBKDF2散列他们的密码。
希望有所帮助!