4

代码:

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-characters'] );

结果:

Warning: password_hash(): Provided salt is too short: 21 expecting 22 

代码:

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersA'] );

结果:

$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32

代码:

echo password_hash("stackoverflow", PASSWORD_DEFAULT, ['salt' => 'twenty-one-charactersB'] );

$2y$10$dHdlbnR5LW9uZS1jaGFyYOVyX13hK9eb4/KXMAkHsAJX..YR7t/32

问题:

如您所见,通过将 A 和 B 附加到 21 个字符串,我们创建了两种不同的 22 个字符的盐,但是,哈希是相同的!那就是第22个字符被忽略了?如果它被忽略,那么为什么它要求 22 个字符的盐?

4

2 回答 2

3

BCrypt 需要一个给定字母的盐:./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. 如您所见,“-”不在其中,这就是您的盐无效的原因。您可以在哈希值中看到明文的有效盐。

在大多数情况下,最好省略 salt 参数。如果没有此参数,该函数将从操作系统的随机源生成加密安全的盐。

password_hash("stackoverflow", PASSWORD_DEFAULT);

尽管如此,当您说 BCrypt 不使用完整的 22 个字符时,您是对的。似乎 BCrypt 只使用 126 位的盐,而不是使用 22 个 base64 编码字符获得的 128 位。有关更多信息,您可以查看此讨论Why does crypt/blowfish generate the same hash ...。

于 2014-10-10T10:54:42.157 回答
1

首先,不要提供自己的盐。你不会比图书馆做得更好。并且使用静态盐(就像您在示例中所做的那样)损害安全性。让它自己生成盐(顺便说一句,我相信让盐进来是我在那个 API 中犯的最大错误)。

至于 21 对 22 个字符,请阅读此答案

基本上,盐是 base64 编码的。这意味着盐的每 6 位编码为 8 位。所以编码盐的每个字节都是 6 位。

21 个字符是 126 位。这意味着只使用了第 22 个字符的一部分(前 2 个解码位)。A使用and获得相同散列的原因B是两个字符的前 2 位相同。

事实上,第 22 个字节只有 4 个唯一的哈希值。

于 2014-12-20T14:53:06.340 回答