PHP &MySQL比较密码
如何检查用户是否输入了正确的登录密码?
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.";
?>
从输出中可以看出,mysql_result
位有问题,但我无法找出正确的方法.
As I can see from the ouput, there's something wrong in the mysql_result
bit, but I can't figure out the right way.
有人可以帮忙吗.
推荐答案
我看到您在数据库中存储密码的哈希值,但为了其他读者的利益,永远不要将密码存储在数据库中的纯文本.你不想成为 喜欢 Monster.com.uk!
I see you are storing a hash of the password in the database, but for the benefit of other readers, never store passwords in plain text in the database. You don't want to be like Monster.com.uk!
您应该使用比 MD5()
更强的散列函数.理想情况下,您应该使用 SHA256.这种散列方法在 PHP 中可以使用 hash()
函数.
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.
您还应该对密码应用随机 salt.为每个用户的帐户存储不同的盐值.这有助于抵御字典攻击和彩虹表攻击.
You should also apply a random salt to the password. Store a different salt value for each user's account. This helps to defeat dictionary attacks and rainbow table attacks.
你应该学会使用 mysqli 扩展而不是旧的 mysql 扩展.Mysqli 支持参数化查询,因此可以减少对某些 SQL 注入攻击的脆弱性.
You should learn to use the mysqli extension instead of the old mysql extension. Mysqli supports parameterized queries, so you can reduce vulnerability to some SQL injection attacks.
这是一些示例代码.我还没有测试它,但它应该非常接近工作:
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;
<小时>
其他人建议查询应该测试 login = ?AND password = ?
但我不喜欢那样做.如果这样做,您将无法知道查找失败是因为登录名不存在,还是因为用户提供了错误的密码.
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.
当然,您不应向用户透露导致登录尝试失败的原因,但您可能需要知道,以便您记录可疑活动.
Of course you shouldn't reveal to the user which caused the failed login attempt, but you may need to know, so you can log suspicious activity.
@Javier 在他的回答中说,您不应该从数据库中检索密码(或本例中的密码哈希).我不同意.
@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 展示了在 PHP 代码中调用 md5()
并将生成的哈希字符串发送到数据库.但这不支持轻松地对密码进行加盐.在 PHP 中进行哈希之前,您必须执行单独的查询来检索此用户的盐.
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.
另一种方法是通过网络将 明文 密码从您的 PHP 应用程序发送到您的数据库服务器.任何窃听您网络的人都可以看到此密码.如果您记录了 SQL 查询,则任何有权访问日志的人都可以看到密码.有上进心的黑客甚至可以潜入垃圾箱寻找旧的文件系统备份媒体,并可能以这种方式读取日志文件!
The alternative is sending the plaintext password 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 应用程序中,将其与用户输入的哈希值(也在 PHP 代码中)进行比较,然后丢弃这些变量.
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.
相关文章