【问题标题】:password_hash, password_verify, MySQL misunderstanding?password_hash、password_verify、MySQL 的误解?
【发布时间】:2014-01-30 22:45:54
【问题描述】:

我似乎无法让这个测试显示来自数据库的散列密码。它可以很好地显示表单中的密码。尝试进行此测试以找出为什么我无法从表单中验证密码与存储在数据库中的密码相比。我读到了一些关于转义散列中的 $ 符号的内容,但我不确定如何使用我正在使用的代码来做到这一点。不管怎样,有些事情是不对的。任何帮助将不胜感激!

require('../connect.php');
$username = $_POST['username-sign-in'];
$password = $_POST['password-sign-in'];
$hashedpassword = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
if (empty($username)) {
    echo 'Please enter your username.';
    exit();
}
if (empty($password)) {
    echo 'Please enter your password.';
    exit();
}
if (isset($username, $password)) {
    $getuser = $connection->prepare('SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?');
    $getuser->bind_param('ss', $username, $hashedpassword);
    $getuser->execute();
    $userdata = $getuser->get_result();
    $row = $userdata->fetch_array(MYSQLI_ASSOC);
    echo 'Password from form: ' . $hashedpassword . '<br />';
    echo 'Password from DB: ' . $row['password'] . '<br />';
    if (password_verify($row['password'], $hashedpassword)) {
        echo 'Success.';
        exit();
    }
    else {
        echo 'Fail.';
        exit();
    }
}
else {
    echo 'Please enter your username and password.';
    $connection->close();
    exit();
}

【问题讨论】:

  • 您不能查询用户提供的密码,这就是使用哈希的全部想法。删除AND password = ? 每次哈希密码时哈希都会不同
  • @PeeHaa 您是否错过了密码被散列进行比较的部分? $hashedpassword = password_hash($password, PASSWORD_BCRYPT, ['cost' =&gt; 12]);
  • @PeeHaa 对于那些似乎一心要责备别人的人,你从来没有提供过可靠的答案或解决方案。
  • 其实它设置为 32...我相信我找到了我的问题 lmao。感谢您所有的帮助!如果问题仍未解决,我会报告。

标签: php mysql password-hash


【解决方案1】:

您是否尝试过更改单引号,例如 ':

$getuser = $connection->prepare('SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?');
$getuser->bind_param('ss', $username, $hashedpassword);

"这样的双引号

$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?");
$getuser->bind_param("ss", $username, $hashedpassword);

另外,你为什么要匹配password?也许这适用于您的测试用例:

$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ?");
$getuser->bind_param("s", $username);

编辑此外,您在进行检查时实际上是对密码进行双重哈希处理:

if (password_verify($row['password'], $hashedpassword)) {

只需这样做:

if (password_verify($password, $row['password'])) {

问题在于password_verify 的语法为:

boolean password_verify ( string $password , string $hash )

您需要在第一个参数中发送普通/非散列密码,然后将散列值放在第二个参数中。试试看。

【讨论】:

  • 将单引号改为双引号有什么好处?
  • @PeeHaa 这是一个想法。就像我的第三个例子一样,我也给出了一个关于删除整个password 在 MySQL 中检查的想法。
  • 想法和猜测属于 cmets 部分。然而这个想法没有多大意义。不过,您在查询中删除密码是正确的
  • @PeeHaa 谢谢你的意见。我期待看到至少另一个人回答这个问题。
  • 谢谢,您的解决方案有效!我拿了AND密码=?出来,现在它正在从数据库中返回字符串。但它仍然给我“失败”。消息,所以我想我仍然对在 password_verify() 中做错了什么感到困惑。
【解决方案2】:

您不能对输入进行哈希处理,然后在数据库中对其进行查询,因为哈希每次都会使用不同的随机盐。所以你可以对同一个密码进行一千次哈希运算,得到 1000 个不同的结果。

您只需在数据库中查询与用户名相关的记录,然后将数据库返回的密码哈希与使用password_verify()的输入密码进行比较。

此外,在创建密码时(使用password_hash())最初将哈希写入数据库时​​,无需转义哈希。 password_hash()在密码验证过程中完全没有使用。

【讨论】:

  • 我想知道如何做一个WHERE user = ? and password = {what the hell to put there} 并检查我是否得到了 1 个结果,但实际上我没有考虑过 WHERE user = ? + 检索散列通行证 + password_verify() !谢谢
【解决方案3】:

快速浏览一下这些函数,您似乎把测试弄错了。

您应该将密码的散列版本存储在数据库中,然后将其与通过 $_POST 提供的密码进行比较.. 然后剩下的就可以了..

$getuser = $connection->prepare('SELECT `password` 
                                        FROM `users` WHERE `username` = ?');
$getuser->bind_param('s', $username);
$getuser->execute();
$userdata = $getuser->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);
echo 'Password from form: ' . $hashedpassword . '<br />';
echo 'Password from DB: ' . $row['password'] . '<br />';
if (password_verify($password, $row['password'])) {
    // $password being $_POST['password-sign-in']
    // $row['password'] being the hashed password saved in the database
    echo 'Success.';
    exit();
} else {
    echo 'Fail.';
    exit();
}

【讨论】:

  • 令人惊讶的是,您拥有唯一一个完全重新编码以解决问题但没有投票的示例……直到现在!刚刚投票!
  • 我活着就是为了被忽视。
  • 诺诺,我接受了你的建议!哈哈,没人理我!我已经在新答案中发布了更新的代码。
  • 您应该将更新放在原始问题中,而不是答案中,因为这会使阅读变得混乱。
  • 数据库中存储的密码是使用password_hash()函数存储的吗?
【解决方案4】:

问题通常是当您对表单中的用户输入进行哈希处理时,它会被哈希处理,就好像它有双引号一样。这就是为什么您看到哈希以 $2y$10 开头的原因……我认为您应该从这一点尝试解决它。如果您要给出答案,请考虑这个

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 2016-04-13
    • 2015-05-10
    • 2022-07-02
    • 2013-02-06
    相关资源
    最近更新 更多