Encryption 在散列函数中,位字符串的大小重要吗?

Encryption 在散列函数中,位字符串的大小重要吗?,encryption,hash,cryptography,sha,pbkdf2,Encryption,Hash,Cryptography,Sha,Pbkdf2,我试图创建一个实现来生成一个密钥,用AES-256加密一个文件,但我对salt大小有一个问题。我计划使用SHA-256并将其与密码短语连接起来,因此,如果连接的位字符串的大小大于256位,这会有区别吗?或者,如果salt和密码短语均为256位,使其连接512位,这会被认为更安全吗?首先,让我们备份并快速查看PBKDF2: PBKDF2生成所需字节数的输出。它通过计算大量的“块”来生成这些字节。每个块都是所选哈希的大小。例如,如果希望派生64字节长的密钥,并且希望使用产生32字节哈希的SHA-25

我试图创建一个实现来生成一个密钥,用AES-256加密一个文件,但我对salt大小有一个问题。我计划使用SHA-256并将其与密码短语连接起来,因此,如果连接的位字符串的大小大于256位,这会有区别吗?或者,如果salt和密码短语均为256位,使其连接512位,这会被认为更安全吗?

首先,让我们备份并快速查看PBKDF2:

PBKDF2生成所需字节数的输出。它通过计算大量的“块”来生成这些字节。每个块都是所选哈希的大小。例如,如果希望派生64字节长的密钥,并且希望使用产生32字节哈希的SHA-256,则将生成2个PBKDF2块。最终输出是这些块的串联

那么如何生成每个块呢

(我将在这里使用RFC术语),块是由函数
F
生成的。此函数接收用户密码
P
、salt
S
、所需的迭代计数
c
和正在生成的块的索引
i
(基于一个)

对于第一个块,函数调用类似于:
F(“MySecretPassword”,“random_salt”,100000,1)
(注意,我使用的是100k次迭代。有关选择此值的更多信息,请参阅。)

回到RFC:

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})
PRF
代表伪随机函数。对于SHA-256,它应该是基于SHA-256的HMAC。该函数首先使用salt
S
与块号
i
连接,为您的密码
P
生成SHA-256 HMAC。然后,函数迭代(
c
次),并将结果与先前的结果进行异或运算。每次迭代都使用SHA-256 HMAC(再次)散列密码
P
,但使用之前的结果作为HMAC密钥

所以-回到你的问题-因为我们使用HMAC,盐的长度不重要**,可以超过256位。当向HMAC提供的密钥(在本例中是您的密码)长度超过哈希输出的长度时,它将对密钥进行哈希运算,以获得精确的256位。如果提供了一个短于256位的密钥,则会对其进行填充,使其正好达到256位。从某种意义上说,这些细节对您的实现是隐藏的,所以您不必担心将盐传递到PBKDF2的时间有多长

**嗯,这在某种程度上确实很重要。参见owlstead对另一个答案的评论。它应该足够长,以挫败彩虹表的使用。(尽管PBKDF2多次应用您的哈希函数,但长salt不如传统的“直接哈希”应用程序重要。)对于我的应用程序,我使用32字节的随机salt,对于使用PBKDF2哈希其密码的每个用户帐户都是唯一的


希望有帮助

为什么HMAC哈希比标准哈希更为必要?为什么使用之前的结果作为密码的简单salt而不是将其用作HMAC函数的密钥不安全?+1,只是一个小问题,还是PKCS#5:“伪随机函数PRF的第一个参数用作HMAC的“密钥”,第二个参数用作HMAC的“文本”。在PBKDF2的情况下,“密钥”因此是密码,“文本”是盐。“@emboss-啊,你是对的,先生,我已经更新了上面的文本。@Jeremy-在我阅读RFC时,HMAC不是严格要求的,但这是他们使用的示例。因为它的密码学特性被很好地理解,并且它被设计为接受一个密钥&秘密,所以它自然适合PBKDF2。