Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何将登录的用户密码与此代码进行比较?_Php_Security_Login - Fatal编程技术网

Php 如何将登录的用户密码与此代码进行比较?

Php 如何将登录的用户密码与此代码进行比较?,php,security,login,Php,Security,Login,我这里有一些登录系统的代码,这纯粹是出于学习目的,是在stackoverflow的伟大人物的帮助下创建的,他们告诉我不要将salt和hash分开存储,而是一起存储。我想知道当用户尝试登录时,我将如何比较密码。如果盐没有储存,我如何比较这两者。有人能帮忙吗 require("constants.php"); $DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname); function createSalt() { $length = mt

我这里有一些登录系统的代码,这纯粹是出于学习目的,是在stackoverflow的伟大人物的帮助下创建的,他们告诉我不要将salt和hash分开存储,而是一起存储。我想知道当用户尝试登录时,我将如何比较密码。如果盐没有储存,我如何比较这两者。有人能帮忙吗

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。此外,即使密码很短,也很难破解,因为不管发生什么,哈希总是一个长字符串。谢谢!我没有意识到这一点。代码被改成实际上不储存盐,没有看到我发布了错误的代码,