PHP的BCrypt无法验证密码
Posted
技术标签:
【中文标题】PHP的BCrypt无法验证密码【英文标题】:BCrypt of PHP cannot verify the password 【发布时间】:2016-02-27 22:03:30 【问题描述】:我测试了 php 的password_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无法验证密码的主要内容,如果未能解决你的问题,请参考以下文章