PHP的BCrypt无法验证密码

Posted

技术标签:

【中文标题】PHP的BCrypt无法验证密码【英文标题】:BCrypt of PHP cannot verify the password 【发布时间】:2016-02-27 22:03:30 【问题描述】:

我测试了 phppassword_verify 验证不正确。我正在使用 centOS 和 PHP 版本 5.3.3。我知道PHP的5.3.3版本没有提供password_hash功能,所以我使用了https://github.com/ircmaxell/password_compat

但是,当我验证它时,总是使用不同的密码返回 true。我的代码有错误吗?

这是我的代码:

    $password = 'k32AlGOPqvCzoh*Sp(Hdrr26]M=lQb00R&W=hew|-|([(03vp==A8%m?l=eA2^bs_|\qVV3WZ';

    $verify_pw = 'k32AlGOPqvCzoh*Sp(Hdrr26]M=lQb00R&W=hew|-|([(03vp==A8%m?l=eA2^bs_|\qVV3WZasdasdasdasdqweqa13123';

    $options = array(
                'cost' => 15
            );

    $hash = password_hash($password, PASSWORD_BCRYPT,$options);

    var_dump(password_verify($verify_pw ,$hash)); // always true

【问题讨论】:

我认为您不会在 password_verify() 中发现太多随机性,但如果您真的认为代码中存在错误,那么您可以创建一个 SSCCE 来证明您的断言并发布github for the compatibility pack 上的问题,或bugs.php.net 上的错误报告 但这真的发生在我身上,这让我很难过。我知道password_verify() 应该可以正常工作,但仍然无法弄清楚是什么原因导致这种情况发生在我的水平上。或者我应该提供更多信息。 bcrypt by design always 给出不同的哈希输出,请看this sof question。或者试试this bcrypt calculator。但是,我想知道您的不同密码是否意味着不同的纯文本或传递到 bcrypt 并吐出不同输出的相同纯文本 - 请验证。另外,请注意哈希中的几个第一个字符,它定义了哈希长度和盐,wiki 对此进行了解释。 重启 apache 后它现在总是返回 true。 好吧,它在 wiki 中声明 Many implementations of bcrypt truncate the password to the first 72 bytes.。尝试缩短您的密码,它按预期工作。 【参考方案1】:

问题不在于您的代码。 Bcrypt 具有来自 56 字节的字符串限制,例如55 个字符

https://www.usenix.org/legacy/events/usenix99/provos/provos_html/node4.html

key 参数是一个秘密加密密钥,它可以是 用户选择的最多 56 个字节的密码(包括终止零 当键是 ASCII 字符串时字节)。

所以你的字符串被截断,这就是为什么你的password_verify总是返回true,因为截断的字符串是相同的。

【讨论】:

非常感谢,因此我需要限制用户字符长度或使用带有随机盐的 SHA-512。我说的对吗? 算法在内部可以更好地管理字符,因此您总共可以访问至少71 个字符。不知道 SHA-512 有没有类似的行为 SHA-512 应该这样做,它会生成字符串的摘要。

以上是关于PHP的BCrypt无法验证密码的主要内容,如果未能解决你的问题,请参考以下文章

[将Bcrypt与phpto哈希密码结合使用不起作用

使用Bcrypt对密码进行加密与解密验证

将用户密码从加盐 SHA1 升级到 bcrypt

如何在 Laravel 中验证 bcrypt 密码?

bcrypt.compare() 在验证密码时总是返回 false

python的bcrypt加密方式验证