php password_verify不使用数据库

Cba*_*bas 14 php mysql passwords mysqli password-protection

我使用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
Run Code Online (Sandbox Code Playgroud)

但每当我尝试将哈希存储在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
Run Code Online (Sandbox Code Playgroud)

我的"密码"列有以下数据类型: 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
Run Code Online (Sandbox Code Playgroud)

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

(string)$hash
utf8_encode($hash)
Run Code Online (Sandbox Code Playgroud)

如果我做:

$hash = settype($hash,"string");
Run Code Online (Sandbox Code Playgroud)

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

Cba*_*bas 12

发现了问题.当我这样做时:

echo strlen($hash)
Run Code Online (Sandbox Code Playgroud)

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

我添加了这一行:

$hash = substr( $hash, 0, 60 );
Run Code Online (Sandbox Code Playgroud)

现在它工作正常.

奇怪的是,没有其他人似乎遇到过这个问题.有关于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个字符?

  • 添加到@martinstoeckli的输入,最好使用`CHAR`数据类型作为数据库中的散列密码字段,并使用`PASSWORD_BCRYPT`常量将60设置为其长度.在这种情况下,哈希值总是60个字符. (2认同)
  • 您与其他解决方案的链接让我得到答案.谢谢!特别是"password_verify not working"导致我的解决方案. (2认同)

Mos*_*esK 10

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