为什么 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 而不是其他东西。

Repl

硬编码密码

如果您使用硬编码哈希并遇到问题,请确保在将值存储在变量中时使用单引号而不是双引号,因为 $ 将被解释为使用双引号时:

<?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.