【问题标题】:Pulling a hashed username from MySQL database从 MySQL 数据库中提取散列用户名
【发布时间】:2018-08-16 18:07:11
【问题描述】:

我正在做一个项目,其中用户名和密码都需要使用 Argon2 进行哈希处理。我在注册和将它们插入数据库时​​都没有遇到任何问题,但我无法提取登录信息。这是我的登录脚本:

<?php  session_start(); ?>
<?php
include 'config.php';
if(isset($_POST['submit'])){
$submittedUser = $_POST['username'];
$submittedPass = $_POST['password'];
$encrypteduser = password_hash($submittedUser, PASSWORD_ARGON2I);

$con=mysqli_connect($servername, $dbusername, $dbpassword, $dbname);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if ($stmt = mysqli_prepare($con, "SELECT * FROM users Where username =?")) {
                    mysqli_stmt_bind_param($stmt, "s", $encrypteduser);
                    mysqli_stmt_execute($stmt);
                    $result = mysqli_stmt_get_result($stmt);
}

while($row = mysqli_fetch_array($result))
{
$username = $row['username'];
$password = $row['password'];
}
if (password_verify($submittedUser, $username) && password_verify($submittedPass, $password))
{
$_SESSION['user']=$username; 

echo "<script> location.href='index.php'; </script>";
        exit;   
}
else
{
 echo "<script> location.href='login.php'; </script>";
        exit;   
}
mysqli_close($con);
}
?>

我目前的理论是生成并存储在$encrypteduser 中的哈希与数据库中的不匹配。这可以解释为什么没有结果被拉出来。有没有办法解决这个问题?

【问题讨论】:

  • password_hash 每次都会生成一个新的盐,所以它不会匹配,为什么需要对用户名进行哈希处理?您可以使用 sha 之类的摘要哈希,或者对其进行加密并使用 sql 中的 aes 函数。但保护用户名是 ott imo
  • 你到底为什么要散列用户名?
  • @LawrenceCherone Jynx..
  • @FunkFortyNiner 谢谢。看起来我现在最终会以纯文本形式保留它们。
  • @EvanEdwards 不客气,埃文。顺便说一句,我之前确实尝试过类似的东西。这是可能的,但有点棘手。我只是不知道我写的剧本在哪里lol!已经好几年了。

标签: php mysql mysqli php-password-hash


【解决方案1】:

这不加密,它散列:

$encrypteduser = password_hash($submittedUser, PASSWORD_ARGON2I);

也就是说,这是一种方式。您(理论上)永远无法从中获取原始文本。每次运行它也会产生不同的结果。因此,您将永远无法运行带有WHERE 子句的查询来挑选一个匹配的用户。相反,您必须遍历系统中的每个用户,对每个用户运行 password_verify()

所以...不要那样做。将用户名保留为纯文本,以便您可以从数据库索引中受益。

【讨论】:

    【解决方案2】:

    您想要做的事情无法完成,因为清楚地存储用户名正是您可以确定需要验证的确切凭据(即表格行)的原因。

    想象一下你还是尝试了。您想验证john.doe。您必须循环每个存储的用户名哈希,获取相应的盐,以便您可以使用john.doe 和当前行盐计算哈希,然后比较两个用户名哈希。如果没有匹配,请转到下一行...直到您最终获得匹配并最终确定要检查的密码哈希。所有这一切,都使用了专门设计为的算法。去图吧。

    【讨论】:

    • 关于您的开业;那是假的;我以前做过,不记得我是怎么做到的。我只是不记得那个脚本在哪里。这很棘手,但可以做到。
    • @FunkFortyNiner 我能想到的唯一解决方法是有一个替代字段来登录(电子邮件、数字 ID ...)。想想密码本身吧:肯定有一个用户选择了password1234,关键是破解者无法知道是哪一个,除非他们验证被盗表上的每个密码。
    猜你喜欢
    • 2015-12-23
    • 2013-05-23
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多