代码:
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个字符的盐,但是,HASHES是相同的!那是第22个字符被忽略了吗?如果被忽略那么为什么要求22个字符盐?
答案 0 :(得分:2)
BCrypt期望给定字母的盐:./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
。你可以看到' - '不在其中,这就是你的盐无效的原因。一个有效的盐,你可以在哈希值中看到明文。
在大多数情况下,最好省略salt参数。如果没有此参数,该函数将从操作系统的随机源生成加密安全的盐。
password_hash("stackoverflow", PASSWORD_DEFAULT);
尽管如此,当你说BCrypt没有使用完整的22个字符时你是对的。似乎BCrypt只使用126位盐,而不是使用22位base64编码字符获得的128位。有关详细信息,请查看此讨论Why does crypt/blowfish generate the same hash...。
答案 1 :(得分:0)
首先,请不提供自己的盐。你不会比图书馆做得更好。使用静态盐(就像您在示例中所做的那样)将危害安全性。只是让它产生自己的盐(顺便说一句,我认为让盐进入是我在该API中犯的最大错误)。
对于21个字符和22个字符,请给this answer一个读数。
基本上,salt是base64编码的。这意味着盐的每6位被编码为8位。所以编码盐的每个字节都是6位。
21个字符是126位。这意味着只使用了第22个字符的一部分(前2个解码位)。您与A
和B
获得相同哈希的原因是两个字符的前2位相同。
实际上,第22个字节只有4个唯一的哈希值。