简体   繁体   English

为什么 password_verify 返回 false?

[英]Why does password_verify return false?

Why does password_verify return false?为什么password_verify返回 false?

This question is intended to be canonical and has been created simply based on the amount of questions that have been asked on this topic.该问题旨在成为规范问题,并且仅根据已就该主题提出的问题数量创建。

There are a variety of reasons why password_verify could be returning false, it can range from the setup of your table to the actual comparing of the password, below are the common causes of it failing. password_verify可能返回 false 的原因有多种,范围从您的表的设置到密码的实际比较,以下是它失败的常见原因。

Column Setup色谱柱设置

  • The length of the password column in your table is too short:您表中密码列的长度太短:

    • If you are using PASSWORD_DEFAULT then it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).如果您使用PASSWORD_DEFAULT ,则建议将结果存储在可以扩展到 60 个字符以上的数据库列中(255 个字符将是一个不错的选择)。
    • If you are using PASSWORD_BCRYPT then it is recommended to store the result in a database column that is 60 characters because PASSWORD_BCRYPT will always result in a 60 character string or FALSE on failure.如果您使用PASSWORD_BCRYPT那么建议将结果存储在 60 个字符的数据库列中,因为PASSWORD_BCRYPT将始终导致 60 个字符的字符串或失败时的 FALSE。

Password Sanitization密码清理

Another common cause is when developers try to "clean" the user's password to prevent it from being malicious, as a result, this causes the input to be different to what is being stored in the table.另一个常见原因是当开发人员试图“清理”用户的密码以防止其被恶意使用时,这会导致输入与表中存储的不同。 It is not even necessary to escape the input, you should use prepared statements instead.甚至不需要转义输入,您应该使用准备好的语句。 You shouldn't even trim the passwords as that could change that which was originally provided.您甚至不应该trim密码,因为这可能会更改最初提供的密码。

Password Verification密码验证

When using password_verify you need to compare the plaintext password with the hash from the database/file/some-other-storage-method, not compare hashes (the implication here being that you need to have stored the hashed password of the user when they register):使用password_verify您需要将明文密码与来自数据库/文件/其他存储方法的散列进行比较,而不是比较散列(这里的含义是您需要在用户注册时存储散列密码):

<?php

$hashed = password_hash('test', PASSWORD_DEFAULT);
$password = 'test';

if (password_verify($password, $hashed)) {
  echo 'success';
} else {
  echo 'fail';
}

?>

Ensure that you are actually passing a hash to password_verify and not something else by dumping it.通过转储,确保您实际上将哈希传递给password_verify而不是其他东西。

Repl复制

Hardcoded Passwords硬编码密码

In the instance that you are using a hardcoded hash and you are facing issues, ensure that you are using single quotes instead of double quotes when storing the value in the variable as the $ will be interpreted in when using double quotes:在您使用硬编码散列并且遇到问题的情况下,请确保在将值存储在变量中时使用单引号而不是双引号,因为使用双引号时将解释$

<?php
// Undefined variable: QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu :1
$incorrect = "$2y$10$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu";

$correct = '$2y$10$QHpfI0MfQWjvsVQWRdFHSOX6WqG8LSf0iFGiKs0Fz0RvqhpFOpAKu';
?>

Repl - Comment out respectively. Repl - 分别注释掉。

Troubleshooting故障排除

var_dump() the hashed password on registration right before you insert it into your database, and var_dump() it again after you fetch it from your database when you are about to password_verify() it. var_dump()是注册时的散列密码,在您将其插入数据库之前,而var_dump()在您将其从数据库中获取后再次使用password_verify() Ensure both hashes are identical.确保两个哈希值相同。 If they are, and the plaintext passwords are identical too, there's no reason for password_verify to fail.如果是,并且明文密码也相同,则password_verify就没有理由失败。 It only fails if the hash gets modified in some way on its roundtrip through the database, or if the plaintext passwords aren't identical.只有当哈希在通过数据库的往返过程中以某种方式被修改,或者明文密码不相同时,它才会失败。

Ensure that you are passing a correct algorithm to password_hash has the second parameter.确保您将正确的算法传递给password_hash具有第二个参数。

Addendum附录

As per the documentation:根据文档:

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.如上所述,在 PHP 7.0 中提供 salt 选项将生成弃用警告。 Support for providing a salt manually may be removed in a future PHP release.在未来的 PHP 版本中可能会删除对手动提供盐的支持。

Check the parameters order检查参数顺序

Just to point something that happened to me, who was reading this same topic trying to solve my problem minutes ago, and can help you to solve the problem as well.只是指出发生在我身上的事情,几分钟前他正在阅读相同的主题试图解决我的问题,并且也可以帮助您解决问题。
See if you are giving the parameters for password_verify() in the right order:查看您是否以正确的顺序提供了 password_verify() 的参数:

password_verify(string $password , string $hash )密码验证(字符串$password ,字符串$hash

password is the password you received by post or other method and are trying to validate.密码是您通过邮寄或其他方式收到并尝试验证的密码。

hash is the hash that you want to compare the password to.(eg The password hash stored in your Data Base) hash是您要比较密码的 hash。(例如,密码 hash 存储在您的数据库中)

It happened to me that I inverted the order of the parameters, so the result wasn't coming as I expected to.我碰巧颠倒了参数的顺序,所以结果没有像我预期的那样出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM