【问题标题】:PHP password_hash function salt length 21 or 22?PHP password_hash 函数盐的长度是 21 还是 22?
【发布时间】:2014-10-10 08:41:22
【问题描述】:

代码:

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 个字符的盐?

【问题讨论】:

  • 你为什么要给自己加盐而不使用默认值?
  • 阅读blowfish默认算法的注释,了解22个字符盐的详细信息

标签: php salt bcrypt password-hash php-password-hash


【解决方案1】:

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

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

password_hash("stackoverflow", PASSWORD_DEFAULT);

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

【讨论】:

  • Bcrypt 确实使用了完整的 22 个字符。但它只使用第 22 位的前 2 位...
  • @ircmaxell - 是的,这实际上是我的意思,我的回答有什么问题?在任何情况下,我都会记住您的出色链接。
【解决方案2】:

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

对于 21 对 22 个字符,请阅读 this answer

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

21 个字符是 126 位。这意味着只使用了第 22 个字符的一部分(前 2 个解码位)。与AB 得到相同哈希的原因是两个字符的前两位相同。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2015-06-29
    相关资源
    最近更新 更多