PHP & MySQL 比较密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/488804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:54:23  来源:igfitidea点击:

PHP & MySQL compare password

phpmysqlloginpasswords

提问by Mussnoon

How does one check to see if a user has typed in the right password to log in?

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

This is what (out of a bunch of combinations...) I am doing:

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

<?

$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.";

?>

As I can see from the ouput, there's something wrong in the mysql_resultbit, but I can't figure out the right way.

正如我从输出中看到的那样,mysql_result有点问题,但我无法找出正确的方法。

Can someone please help.

有人可以帮忙吗。

回答by Bill Karwin

I see you are storing a hash of the password in the database, but for the benefit of other readers, neverstore passwords in plain text in the database. You don't want to be like Monster.com.uk!

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

You should use a stronger hashing function than MD5(). Ideally you should use SHA256. This hash method is available in PHP using the hash()function.

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

You should also apply a random saltto the password. Store a different salt value for each user's account. This helps to defeat dictionary attacks and rainbow tableattacks.

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

You should learn to use the mysqliextension instead of the old mysql extension. Mysqli supports parameterized queries, so you can reduce vulnerability to some SQL injection attacks.

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

Here is some example code. I haven't tested it, but it should be pretty close to working:

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

$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;


Some other people suggest the query should test for login = ? AND password = ?but I don't like to do that. If you do this, you can't know if the lookup failed because the login didn't exist, or because the user provided a wrong password.

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

Of course you shouldn't reveal to the user which caused the failed login attempt, but youmay need to know, so you can log suspicious activity.

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



@Javier says in his answer that you shouldn't retrieve the password (or password hash in this case) from the database. I don't agree.

@Javier 在他的回答中说你不应该从数据库中检索密码(或在这种情况下的密码哈希)。我不同意。

Javier shows calling md5()in PHP code and sending that the resulting hash string to the database. But this doesn't support salting the password easily. You have to do a separate query to retrieve this user's salt before you can do the hash in PHP.

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

The alternative is sending the plaintextpassword over the network from your PHP app to your database server. Anyone wiretapping your network can see this password. If you have SQL queries being logged, anyone who gains access to the logs can see the password. Motivated hackers can even dumpster-dive to find old filesystem backup media, and might read the log files that way!

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

The lesser risk is to fetch the password hash string from the database into the PHP app, compare it to the hash of the user's input (also in PHP code), and then discard these variables.

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

回答by BrynJ

Firstly, make sure you properly escape your variables before using them in the query - use mysql_real_escape_string().

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

Then, why not use the MySQL MD5 function to check for a valid login in your query?

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

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

Then just use mysql_num_rows() to count the number of returned rows.

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

回答by Javier

some points:

几点:

  • Do NOT insert string data in the query string. Especially user-provided data. what would happen if i login with "Robert' ;drop table customer"?. Use either the escaping routines, or (far better) use prepared statements and bind parameters.
  • Do NOT store cleartext passwords in your database. (you're ok on this)
  • Do NOT retrieve passwords from your database.
  • 不要在查询字符串中插入字符串数据。尤其是用户提供的数据。如果我使用“Robert' ; drop table customer”登录会发生什么?。使用转义例程,或者(更好)使用准备好的语句和绑定参数。
  • 不要在您的数据库中存储明文密码。(你没问题)
  • 不要从您的数据库中检索密码。

what i usually do is something like:

我通常做的是这样的:

$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.";
}

回答by Uday Hiwarale

Get password from user from FORM POST method and convert $_POST['password'] //from form// into appropriate format in php/jsp/any other then compare with formatted password in your database

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

Generally md5 encryption is used whene you can compare md45('{$_POST['password']}')= present in your db; or generally mysql use password('your password') command while creating password hence first concert your $_POST['password'] into mysqli_query and mysqli_fetch_array to get encrypted password value and then compare.

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

回答by PodTech.io

Greater than PHP 5.6, you can use hash_compare function.

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

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