Php 如何将登录的用户密码与此代码进行比较?
我这里有一些登录系统的代码,这纯粹是出于学习目的,是在stackoverflow的伟大人物的帮助下创建的,他们告诉我不要将salt和hash分开存储,而是一起存储。我想知道当用户尝试登录时,我将如何比较密码。如果盐没有储存,我如何比较这两者。有人能帮忙吗Php 如何将登录的用户密码与此代码进行比较?,php,security,login,Php,Security,Login,我这里有一些登录系统的代码,这纯粹是出于学习目的,是在stackoverflow的伟大人物的帮助下创建的,他们告诉我不要将salt和hash分开存储,而是一起存储。我想知道当用户尝试登录时,我将如何比较密码。如果盐没有储存,我如何比较这两者。有人能帮忙吗 require("constants.php"); $DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname); function createSalt() { $length = mt
require("constants.php");
$DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
function createSalt() {
$length = mt_rand(64, 128);
$salt = '';
for ($i = 0; $i < $length; $i++) {
$salt .= chr(mt_rand(33, 255));
}
return $salt;
}
//Salt function created by ircmaxell
function registerNewUser() {
//Check to see if Username Is In Use//
$q = $DBH->prepare("SELECT id FROM users WHERE username = ?");
$username = filter_var($username, FILTER_SANITIZE_STRING);
$data = array($username);
$q->execute($data);
$row = $q->fetch();
if ($row === false) {
//If Username Is Not Already In Use Insert Data//
$hash = hash('sha256', $pass);
$salt = createSalt();
$hash = hash('sha256', $salt . $hash . $pass); //UPDATED
$data = array($username, $hash, $salt);
$qInsert = $DBH->prepare(
"INSERT INTO users (username, password, salt) values (?, ?, ?)"
);
$qInsert->execute($data); //Inserts User Data Into Table//
}
}
require(“constants.php”);
$DBH=newmysqli($dbhost、$dbuser、$dbpass、$dbname);
函数createSalt(){
$length=mt_rand(64128);
$salt='';
对于($i=0;$i<$length;$i++){
$salt.=克朗(33255克朗);
}
退还$salt;
}
//由ircmaxell创建的Salt函数
函数寄存器newuser(){
//检查用户名是否正在使用//
$q=$DBH->prepare(“从用户名=?”的用户中选择id”);
$username=filter\u var($username,filter\u SANITIZE\u STRING);
$data=数组($username);
$q->execute($data);
$row=$q->fetch();
如果($row==false){
//如果用户名尚未使用,请插入数据//
$hash=hash('sha256',$pass);
$salt=createSalt();
$hash=hash('sha256',$salt.$hash.$pass);//已更新
$data=array($username,$hash,$salt);
$qInsert=$DBH->prepare(
“在用户(用户名、密码、salt)中插入值(?,?)”
);
$qInsert->execute($data);//将用户数据插入表//
}
}
您必须查询数据库以检索用户行(如果有),获取salt并对用户提供的密码使用相同的算法。如果两个哈希值都匹配,则用户提供了一个良好的密码
编写一些代码会产生如下效果:
$qSelect = $DBH->prepare('SELECT salt,password FROM users WHERE username = ?');
$qSelect->execute();
$qSelect->bind_result($salt, $db_password);
$qSelect->fetch();
if($salt == null){
// username doesn't exist
return;
}
$hash = hash('sha256', $pass);
$hash = hash('sha256', $salt . $hash . $pass);
if($hash == $db_password){
// login ok
} else {
// login nok
}
您必须查询数据库以检索用户行(如果有),获取salt并对用户提供的密码使用相同的算法。如果两个哈希值都匹配,则用户提供了一个良好的密码 编写一些代码会产生如下效果:
$qSelect = $DBH->prepare('SELECT salt,password FROM users WHERE username = ?');
$qSelect->execute();
$qSelect->bind_result($salt, $db_password);
$qSelect->fetch();
if($salt == null){
// username doesn't exist
return;
}
$hash = hash('sha256', $pass);
$hash = hash('sha256', $salt . $hash . $pass);
if($hash == $db_password){
// login ok
} else {
// login nok
}
做同样的工作:
$hash = hash('sha256', $row['salt'] . hash('sha256', $pass) . $pass);
if ($row['password'] == $hash) {
// the password is correct
}
其中,$row
已根据用户名从数据库中获取,$pass
是从表单中检索到的密码
此外,在散列中包含密码两次是没有意义的:散列和纯文本
$hash = hash('sha256', $salt . $pass); // this would be enough
做同样的工作:
$hash = hash('sha256', $row['salt'] . hash('sha256', $pass) . $pass);
if ($row['password'] == $hash) {
// the password is correct
}
其中,$row
已根据用户名从数据库中获取,$pass
是从表单中检索到的密码
此外,在散列中包含密码两次是没有意义的:散列和纯文本
$hash = hash('sha256', $salt . $pass); // this would be enough
问题:
1) 您创建hash+salt密码散列的方法是非传统的。严格说来,这不是一个问题,只是看起来并不是你想要的。虫族清楚地说明了这一点
2) 您的数据库插入要求用户名是唯一的列并且缺少一些异常处理,或者容易受到竞争的影响,这将导致多个用户使用相同的用户名和不同的密码(如果是密钥,则使用不同的ID)问题:
1) 您创建hash+salt密码散列的方法是非传统的。严格说来,这不是一个问题,只是看起来并不是你想要的。虫族清楚地说明了这一点
2) 您的数据库插入要求用户名是唯一的列并且缺少一些异常处理,或者它容易受到竞争的影响,这将导致多个用户使用相同的用户名和不同的密码(如果这是密钥,则使用不同的ID)我必须将盐存储在某个位置吗?因为再次运行salt的代码不会产生相同的结果,所以我想不出其他方法来重新创建哈希。@mcbeav:相同的salt和相同的密码应该总是产生相同的哈希。“我必须将盐存储在某个地方吗?”--您已经这样做了-您将其存储在
salt
字段中。@RageZ:他正在使用mysqli-抱歉,我发错代码了。一切都是正确的,除了我应该在代码中取出它(存储盐),但我假设我必须存储盐才能工作。这是我真正的问题。对不起,我需要把盐存放在什么地方吗?因为再次运行salt的代码不会产生相同的结果,所以我想不出其他方法来重新创建哈希。@mcbeav:相同的salt和相同的密码应该总是产生相同的哈希。“我必须将盐存储在某个地方吗?”--您已经这样做了-您将其存储在salt
字段中。@RageZ:他正在使用mysqli-抱歉,我发错代码了。一切都是正确的,除了我应该在代码中取出它(存储盐),但我假设我必须存储盐才能工作。这是我真正的问题。抱歉。@zerkms:这并不是毫无意义的,因为它增加了破解密码的复杂性。因为你必须做两遍sha256。此外,即使密码很短,也很难破解,因为不管发生什么,哈希总是一个长字符串。谢谢!我没有意识到这一点。代码被更改为实际上不存储盐,没有看到我发布了错误的代码,但我假设我必须将盐存储在这里才能工作。将盐存储在DB中是否会降低安全性?@RageZ:事实上,在这一部分中,2的计算速度比1慢,但事实上,更长的字符串更安全(因为它是从相同的数据准备的)@mcbeav:@zerkms:是的,你是对的,至少这会使密码更复杂,但我想不会更安全。@zerkms:这并不是毫无意义的,因为它会增加破解密码的复杂性。因为你必须做两遍sha256。此外,即使密码很短,也很难破解,因为不管发生什么,哈希总是一个长字符串。谢谢!我没有意识到这一点。代码被改成实际上不储存盐,没有看到我发布了错误的代码,