php password_verify数据库不起作用

2022-08-30 19:53:25

我正在使用php 5.4与此向后兼容性脚本:https://github.com/ircmaxell/password_compat/blob/master/lib/password.php

不过这并不重要,因为我可以在我的注册函数中运行哈希和验证过程:

$hash = password_hash($pass, PASSWORD_DEFAULT);

echo $pass;
echo $hash;

if( password_verify($pass,$hash) )
    echo 'success';
else echo 'failure';

//success is always shown

//EXAMPLE INPUT
$pass = 'password';

//EXAMPLE OUTPUT
password$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYSsuccess

但是每当我尝试将哈希存储在MySQL数据库中,然后为验证函数检索它时,它总是失败。这是我的登录功能:

function user_login( $mysqli, $email, $pass ){    

        $err_msg = 'login: '.$mysqli->error.' | '.$email;

        if( $stmt = $mysqli->prepare('SELECT password FROM users WHERE email=?') ) :

            if( !$stmt->bind_param('s', $email) ) log_sql_error( $err_msg );
            if( !$stmt->execute() ) log_sql_error( $err_msg );
            if( !$stmt->bind_result( $hash ) ) log_sql_error( $err_msg );
            if( $stmt->fetch() === FALSE ) log_sql_error( $err_msg );
            if( !$stmt->close() ) log_sql_error( $err_msg );

            //I can see that these values are identical to the ones
            //echoed out in the registration function
            echo $pass;
            echo $hash;

            if( password_verify($pass,$hash) )
                echo 'success';
            else echo 'failure';

        else : log_sql_error( $err_msg );
        endif;
}
//failure is always shown

//EXAMPLE INPUT
$pass = 'password';

//EXAMPLE OUTPUT
password$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYSfailure

我的“密码”列具有以下数据类型:VARCHAR(255) NOT NULL

没有显示php错误,所以我唯一能想到的是,哈希值在从数据库中出来时的格式与它进入时的格式不同,但是当我回显这些值时,它们似乎是相同的。

否则我该如何调试这个/我的代码有什么问题?

谢谢

更新:

这肯定与编码有关:

$hardcode_hash = '$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS';

echo $hash;
echo '<br/>';
echo $hardcode_hash;
echo '<br/>';

if( $hash == $hardcode_hash )
    echo 'success';
else echo 'failure';

//OUTPUT
$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS
$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS
failure

如何重新格式化SQL值以匹配password_hash的输出?以下是我尝试过的方法:

(string)$hash
utf8_encode($hash)

如果我这样做:

$hash = settype($hash,"string");

if($hash == $hardcode_hash)返回 true,但仍返回 falsepassword_verify($pass, $hash)


答案 1

发现问题。当我这样做时:

echo strlen($hash)

它打印了90,这很奇怪,因为当我打印出成功/失败消息时,末尾肯定没有空格,并且该字段的varchar长度为255

我添加了这行:

$hash = substr( $hash, 0, 60 );

现在它工作正常。

奇怪的是,似乎没有其他人遇到过这个问题。有关于password_verify的类似帖子,但没有一个需要这种类型的转换,或者任何转换:

php password_verify不起作用

password_verify php 不匹配

http://forums.phpfreaks.com/topic/283407-need-help-with-password-verify/

使用 PHP 5.5 的password_hash和password_verify功能

困扰我的一件事是,这会阻止代码向前兼容。当默认值更改时,我如何知道哈希长度为 60 个字符?


答案 2

我在password_verify()上遇到了同样的问题。对我来说,我已经声明了我的用户名和密码为VARCHAR(50)。.因此,它没有在我的数据库中插入哈希值,这显然超过50个字符。因此,每次我使用password_verify()时,我都会得到一个错误。我将数据库值更改为 varchar(255)。再次插入数据,经过测试,它的工作原理。


推荐