6

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

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

<?

$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位有问题,但我无法找出正确的方法。

有人可以帮忙吗。

4

5 回答 5

18

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

您应该使用比MD5(). 理想情况下,您应该使用 SHA256。在 PHP 中使用该hash()函数可以使用此哈希方法。

您还应该对密码应用随机盐。为每个用户的帐户存储不同的盐值。这有助于击败字典攻击和彩虹表攻击。

你应该学会使用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 展示了调用md5()PHP 代码并将生成的哈希字符串发送到数据库。但这不支持轻松地对密码进行加盐。您必须执行单独的查询来检索此用户的盐,然后才能在 PHP 中执行散列。

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

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

于 2009-01-28T19:02:43.090 回答
3

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

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

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

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

于 2009-01-28T18:52:26.027 回答
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.";
}
于 2009-01-28T18:51:46.543 回答
0

从 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 以获取加密的密码值,然后进行比较。

于 2013-10-12T21:25:08.657 回答
0

大于 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

于 2016-12-30T12:08:03.783 回答