【问题标题】:PHP & MySQL compare passwordPHP & MySQL 比较密码
【发布时间】:2010-10-04 01:55:08
【问题描述】:

如何检查用户是否输入了正确的登录密码?

这就是我正在做的(从一堆组合中......):

<?

$login = $_POST['login'];
$password = $_POST['password'];

mysql_connect('localhost', 'root', 'abc123');

mysql_select_db('aun_vox') or die(mysql_error());

$q = mysql_query("SELECT password FROM customer WHERE login='$login'");
$db_pass = mysql_result($q, 0);

if(md5($password) == $db_pass)
{
    echo "You did it.";
}

else echo "Wrong.";

?>

从输出中我可以看出,mysql_result 位有问题,但我无法找出正确的方法。

有人可以帮忙吗。

【问题讨论】:

  • 我们在 stackoverflow 不回答有关登录的问题。我们更愿意以非常详细的技术细节来解释如何清理用户输入。安全比拥有一个有效的网站要好。
  • @Grant:你在开玩笑吧?
  • 请注意,此页面上的答案已过时,因此不安全,请查看此question

标签: php mysql login passwords


【解决方案1】:

几点:

  • 不要在查询字符串中插入字符串数据。尤其是用户提供的数据。如果我使用“Robert' ;drop table customer”登录会发生什么?使用转义例程,或者(更好)使用准备好的语句和绑定参数。
  • 不要在数据库中存储明文密码。 (你没问题)
  • 不要从您的数据库中检索密码。

我通常做的事情是这样的:

$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?");
bindvalue ($q, $_POST['login']);
bindvalue ($q, md5($_POST['password']));
$id = execprepared ($q);

if($id) {
    echo "You did it.";
} else {
    echo "Wrong.";
}

【讨论】:

  • 我们称他为小鲍比桌。
  • 您可能应该指出您在这里没有使用原生 PHP 代码。 bindvalue() 让我有点困惑,在 php.net 上找不到它之后更是如此。终于在网上找到了 PHP 数据对象 (PDO),其中涵盖了您示例中的信息。
【解决方案2】:

首先,确保在查询中使用变量之前正确转义变量 - 使用 mysql_real_escape_string()。

那么,为什么不使用 MySQL MD5 函数来检查查询中的有效登录?

SELECT login FROM customer WHERE login='$login' AND password = MD5('$password')

然后只需使用 mysql_num_rows() 来计算返回的行数。

【讨论】:

    【解决方案3】:

    我看到您将密码的哈希值存储在数据库中,但为了其他读者的利益,从不将密码以纯文本形式存储在数据库中。你不想成为like Monster.com.uk

    您应该使用比MD5() 更强的散列函数。理想情况下,您应该使用 SHA256。这种散列方法在 PHP 中可以使用 hash() 函数。

    您还应该对密码应用一个随机的salt。为每个用户的帐户存储不同的盐值。这有助于抵御字典攻击和rainbow table 攻击。

    你应该学会使用mysqli 扩展而不是旧的mysql 扩展。 Mysqli 支持参数化查询,因此可以减少对某些 SQL 注入攻击的脆弱性。

    这是一些示例代码。我还没有测试它,但它应该非常接近工作:

    $input_login = $_POST['login'];
    $input_password = $_POST['password'];
    
    $stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
    $stmt->bind_param("s", $input_login);
    $stmt->execute();
    $stmt->bind_result($password_hash, $salt);
    
    while ($stmt->fetch()) {
      $input_password_hash = hash('sha256', $input_password . $salt);
      if ($input_password_hash == $password_hash) {
        return true;
      }
      // You may want to log failed password attempts here,
      // for security auditing or to lock an account with
      // too many attempts within a short time.
    }
    $stmt->close();
    
    // No rows matched $input_login, or else password did not match
    return false;
    

    其他人建议查询应该测试login = ? AND password = ?,但我不喜欢这样做。如果这样做,您将无法知道查找失败是因为登录名不存在,还是因为用户提供了错误的密码。

    当然,您不应向用户透露导致登录尝试失败的原因,但可能需要知道,以便您记录可疑活动。


    @Javier 在他的回答中说,您不应该从数据库中检索密码(或本例中的密码哈希)。我不同意。

    Javier 展示了在 PHP 代码中调用 md5() 并将生成的哈希字符串发送到数据库。但这不支持轻松地对密码进行加盐。在 PHP 中进行哈希之前,您必须执行单独的查询来检索此用户的盐。

    另一种方法是通过网络将 明文 密码从您的 PHP 应用程序发送到您的数据库服务器。任何窃听您网络的人都可以看到此密码。如果您记录了 SQL 查询,则任何有权访问日志的人都可以看到密码。有上进心的黑客甚至可以潜入垃圾箱寻找旧的文件系统备份媒体,并可能通过这种方式读取日志文件!

    风险较小的是将密码哈希字符串从数据库中提取到 PHP 应用程序中,将其与用户输入的哈希值(也在 PHP 代码中)进行比较,然后丢弃这些变量。

    【讨论】:

    • 您的代码中只缺少一件事。 mysqli_prepare() 有两个参数——第一个是 mysqli_connect() 语句的结果。因为我使用的是 mysql_connect() ,所以它不起作用。但修改后,它工作正常。感谢您的帮助。
    • 谢谢你的收获,我已经修好了。不过,我没有显示连接到数据库。只是假设你有一个实时的 $mysqli 对象。
    • mysqli 太可怕了,无法使用(可悲)
    • @cletus:相对于什么? PDO_mysql? mysql扩展? PHP 本身?
    • @Bill:mysqli 有两个严重的问题,其中一个(LONGTEXT 列上的段错误)在三年内没有得到修复。另一个是随机的“金丝雀问题”错误(或类似的东西;但我当时放弃了。与 mysql 完美配合)。是 mysql 或 PDO。
    【解决方案4】:

    通过 FORM POST 方法从用户获取密码并将 $_POST['password'] //from form// 转换为 php/jsp/any other 中的适当格式,然后与数据库中的格式化密码进行比较

    当您可以比较数据库中存在的 md45('{$_POST['password']}')= 时,通常会使用 md5 加密; 或者一般 mysql 在创建密码时使用 password('your password') 命令,因此首先将您的 $_POST['password'] 放入 mysqli_query 和 mysqli_fetch_array 以获取加密的密码值,然后进行比较。

    【讨论】:

      【解决方案5】:

      PHP 5.6 以上,可以使用 hash_compare 函数。

       $users_password = hash(sha256,$salt.$post_password);
      
       if (hash_equals($users_dbpassword, $users_password)) {
            //pass is good
       } else {
             // pass failed
       }
      

      http://php.net/manual/ru/function.hash-equals.php

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2013-05-26
      • 2012-04-07
      • 1970-01-01
      相关资源
      最近更新 更多