为什么 password_verify return 是假的?
Why does password_verify return false?
为什么 password_verify
return 是假的?
这个问题旨在成为规范问题,并且只是根据就此主题提出的问题数量创建的。
password_verify
可能返回 false 的原因有很多种,范围从您 table 的设置到密码的实际比较,以下是常见的原因失败。
列设置
您table中密码栏的长度太短:
- 如果您正在使用
PASSWORD_DEFAULT
,那么建议将结果存储在可以扩展到超过 60 个字符的数据库列中(255 个字符将是一个不错的选择)。
- 如果您使用
PASSWORD_BCRYPT
,则建议将结果存储在 60 个字符的数据库列中,因为 PASSWORD_BCRYPT
将始终生成 60 个字符的字符串或失败时为 FALSE。
密码清理
另一个常见原因是当开发人员试图 "clean" 用户密码以防止它被恶意使用时,这导致输入与 [=76= 中存储的内容不同].甚至没有必要对输入进行转义,您应该改用准备好的语句。您甚至不应该 trim
密码,因为这可能会更改最初提供的密码。
密码验证
当使用 password_verify
时,您需要将明文密码与来自 database/file/some-other-storage-method 的散列进行比较,而不是比较散列(这里的含义是您需要存储用户的散列密码当他们注册时):
<?php
$hashed = password_hash('test', PASSWORD_DEFAULT);
$password = 'test';
if (password_verify($password, $hashed)) {
echo 'success';
} else {
echo 'fail';
}
?>
通过转储确保您实际上是将哈希传递给 password_verify
而不是其他东西。
硬编码密码
如果您使用硬编码哈希并遇到问题,请确保在将值存储在变量中时使用单引号而不是双引号,因为 $
将被解释为使用双引号时:
<?php
// Undefined variable: QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu :1
$incorrect = "y$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu";
$correct = 'y$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu';
?>
Repl - 分别注释掉。
疑难解答
var_dump()
注册时的散列密码,然后再将其插入数据库,然后 var_dump()
在您即将 password_verify()
从数据库中获取密码后再次输入.确保两个哈希值相同。如果是,并且明文密码也相同,则 password_verify
没有理由失败。仅当散列在其通过数据库的往返过程中以某种方式被修改,或者明文密码不相同时才会失败。
确保您将正确的算法传递给 password_hash
具有第二个参数。
附录
根据文档:
Caution It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.
As noted above, providing the salt option in PHP 7.0 will generate a deprecation warning. Support for providing a salt manually may be removed in a future PHP release.
为什么 password_verify
return 是假的?
这个问题旨在成为规范问题,并且只是根据就此主题提出的问题数量创建的。
password_verify
可能返回 false 的原因有很多种,范围从您 table 的设置到密码的实际比较,以下是常见的原因失败。
列设置
您table中密码栏的长度太短:
- 如果您正在使用
PASSWORD_DEFAULT
,那么建议将结果存储在可以扩展到超过 60 个字符的数据库列中(255 个字符将是一个不错的选择)。 - 如果您使用
PASSWORD_BCRYPT
,则建议将结果存储在 60 个字符的数据库列中,因为PASSWORD_BCRYPT
将始终生成 60 个字符的字符串或失败时为 FALSE。
- 如果您正在使用
密码清理
另一个常见原因是当开发人员试图 "clean" 用户密码以防止它被恶意使用时,这导致输入与 [=76= 中存储的内容不同].甚至没有必要对输入进行转义,您应该改用准备好的语句。您甚至不应该 trim
密码,因为这可能会更改最初提供的密码。
密码验证
当使用 password_verify
时,您需要将明文密码与来自 database/file/some-other-storage-method 的散列进行比较,而不是比较散列(这里的含义是您需要存储用户的散列密码当他们注册时):
<?php
$hashed = password_hash('test', PASSWORD_DEFAULT);
$password = 'test';
if (password_verify($password, $hashed)) {
echo 'success';
} else {
echo 'fail';
}
?>
通过转储确保您实际上是将哈希传递给 password_verify
而不是其他东西。
硬编码密码
如果您使用硬编码哈希并遇到问题,请确保在将值存储在变量中时使用单引号而不是双引号,因为 $
将被解释为使用双引号时:
<?php
// Undefined variable: QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu :1
$incorrect = "y$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu";
$correct = 'y$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu';
?>
Repl - 分别注释掉。
疑难解答
var_dump()
注册时的散列密码,然后再将其插入数据库,然后 var_dump()
在您即将 password_verify()
从数据库中获取密码后再次输入.确保两个哈希值相同。如果是,并且明文密码也相同,则 password_verify
没有理由失败。仅当散列在其通过数据库的往返过程中以某种方式被修改,或者明文密码不相同时才会失败。
确保您将正确的算法传递给 password_hash
具有第二个参数。
附录
根据文档:
Caution It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.
As noted above, providing the salt option in PHP 7.0 will generate a deprecation warning. Support for providing a salt manually may be removed in a future PHP release.