【问题标题】:How can I compare a hashed password with user input?如何将散列密码与用户输入进行比较?
【发布时间】:2015-05-30 22:18:43
【问题描述】:

我正在尝试匹配并验证用户通过 $_POST 输入的密码和数据库中的散列密码。问题是,当我对输入密码进行哈希处理时,BCRYPT 每次都会产生一个新的哈希值,这意味着没有两个哈希值是相同的,这不会给我匹配。我怎么可能匹配 BCRYPT 散列密码?感谢您的帮助!

登录:

$password = password_hash(htmlentities($_POST['password']), PASSWORD_BCRYPT, array(
'cost'=>14)); 

$stmt = $mcon->prepare("SELECT `password` FROM members WHERE password=:password");
$stmt->bindParam(":password", $password);
$stmt->execute();

//get_result
$data_array = $stmt->fetch(PDO::FETCH_ASSOC);
//echo passwords
echo  'Password from form: ' . $password . '<br />';
echo 'Password from DB: ' . $data_array['password'] . '<br />';
//verify password
if (password_verify($password , $data_array)) {
    echo 'success';
    exit();
}else{
    echo 'Try again m9';
    exit();
}

//if $_POST password and $hashedpassword match then start session

$stmt->close();
$mcon->close();

【问题讨论】:

  • @pid 问题是,每个人都使用自己的盐,但我个人认为这不是一个好主意,虽然它适用于密码验证,但这不是我想要的。无论如何感谢您的帮助!
  • 你在使用 PHP 5.5 吗?那个版本有新的password_xxx功能吧? password_verify() 检查登录尝试和 password_hash() 对其进行编码?也许这可以帮助你? stackoverflow.com/a/17786721/1138321
  • 您可能希望在 SQL 查询中删除 password 周围的反引号。它们可能是您的问题的原因。 SQL 不会使用这些,除非您需要文字,在这种情况下,您将始终获得 password 字符串本身,而不是数据库值。

标签: php pdo hash


【解决方案1】:

这不是答案,但对您仍然有用。不要过滤密码(WHERE 子句),而是过滤用户名:

$stmt = $mcon->prepare("SELECT password FROM members WHERE username=:username");
$stmt->bindParam(":username", $username);
$stmt->execute();

此外,不要将密码存储在数据库中,即使是加密的也不要。只是存储了哈希值和盐值。通过随机化更改每个密码的盐值。

如果你真的需要实现安全,你至少应该阅读this 之类的东西,但事实是你阅读和学习的越多越好,你真正需要知道多少才能拥有一个没有限制安全的网站,如果真的存在这样的事情的话。

也许框架会更好,例如 Laravel 或 Symfony。他们有插件来处理这些细节,你不可能希望编写任何接近这些安全标准的东西。

只是为了向您展示有关 Top 10 PHP attacks on OWASP 的代码是多么不安全。

【讨论】:

  • 我不将我的密码存储在数据库中,只存储哈希和盐。我的注册页面处理了所有的安全问题,所以如果我对你诚实的话,这并不是一个真正的问题。我不使用 Laravel 的唯一原因是因为我觉得这有点作弊,而且如果 Laravel 失败,一旦攻击开始,我就无法更改任何代码。非常感谢您的反馈,我会考虑!
  • 使用框架不是“作弊”,我对您所说的攻击/更改代码感到困惑。您可以像自己编写的代码一样轻松地更改 Laravel 应用程序的代码。
  • @ceejayoz 哈哈,我的意思是我想完全了解我制作的东西,并且几乎预先包装了一些东西,我觉得虽然它已经完成了,但要根据我的需要进行修改需要一段时间。如果您知道我的意思,我真的宁愿建立一个坚实的基础,然后自己涂上它。无论如何感谢您的反馈!
  • 您是否也拒绝乘坐不是您自己制造的车辆,或者拒绝吃不是您种植/狩猎/烹饪的食物?框架的全部意义在于提供广泛的“坚实基础”,这对于单个编码人员来说几乎是不可能自己产生的。说真的,试试 Laravel 之类的东西,并利用数十/数百/数千其他已经为您完成繁重工作的人所涉及的安全性、最佳实践和易于编码的优势。
  • @jellal 我们非常理解您的意思,我们的建议是:不要。您认为您无法信任 FOSS(开源代码),但事实是您无法信任自己,因为您甚至无法估计您不了解该主题的多少。跨度>
【解决方案2】:

代码中的另一个错误:函数password_verify 需要哈希字符串作为第二个参数。不要将此与 php-hash-datastructure 混淆。所以你需要这样称呼它:

$password_input = $_POST['password'];
password_verify($password_input , $data_array['password']);

http://php.net/manual/de/function.password-verify.php

当然,PID的答案也是对的,你需要用用户名而不是密码来查找用户。

【讨论】:

  • 我在放之前这样做了,但它不起作用。忘了把它包括在这里。无论如何感谢您的帮助!
  • 当然没有用,因为它不是唯一的错误。我已经添加了password_verify函数的文档链接,大家可以自己查。
  • 哈哈,我的意思是我已经这样做了,只是忘了在这里输入。再次感谢。
  • password_verify 期望用户输入作为第一个参数...不是散列值 (password_verify($_POST['password'], $data_array['password']))
  • 是的,DarkBee 也是正确的。 password_verify 正在内部计算哈希,这就是函数的用途!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 2020-09-21
相关资源
最近更新 更多