【问题标题】:PHP hashed & salted passwordPHP 哈希和加盐密码
【发布时间】:2014-07-26 02:14:04
【问题描述】:

所以我正在创建一个简单的 PHP 注册/登录表单。我为密码创建了一个哈希和盐,但我似乎无法使用正确的密码登录。就像它错误地散列一样?请记住,我不是专业人士。

注册码,工作正常,散列密码并存储盐。

if ($errors === 0) {
            $salt = mcrypt_create_iv(32); 
            $signpassword = DatabaseHelpers::hash($signpassword, $salt);
            query("INSERT INTO user_info(Username, Email, Password, Salt) VALUES(:signusername, :email, :signpassword, :salt)",
            array('signusername' => $signusername, 'email' => $email, 'signpassword' => $signpassword, 'salt' => $salt),
            $conn);
            $successstatus = 'You have successfully registered';
}  
};

登录代码

$username = $_POST['username'];
$password = $_POST['password'];

function verify($password, $salt) {
 hash('sha256', $password . $salt);
    }//function for verifying the password, doesn't seem to be working

if (empty($username) || empty($password)) {
    $logstatus = 'Please input your username and password';
    //update login attempts
} else {

    $salts = $conn->prepare('SELECT salt FROM user_info where username=?');
    $salts->bindParam(1, $username);
    $salts->execute();
    $salts = $salts->fetch(PDO::FETCH_ASSOC);
    foreach ($salts as $slt) {
        $slt = $salt;
    }//gets the salt

    $hashedpassword = verify($password, $salt);//
    $stmt = $conn->prepare('SELECT * FROM user_info where username=? and password=?');
    $stmt->bindParam(1, $username);
    $stmt->bindParam(2, $hashedpassword);
    $stmt->execute();

    function start($username, $sessionName){
        header(  'Location: logging.php') ;
        session_start();
        $_SESSION['username'] = $username;  
    };


    if($stmt->rowCount() == 1) {
       start($username, $sessionName);
    } else {
        $logstatus = 'Username or password incorrect.';
    }
};};};

当我输入正确的密码时,它总是执行 else 语句。如果我注释掉散列并从数据库中输入散列 pw,它会让我登录吗?我知道这可能真的很愚蠢,但我看不到。有人帮我吗?快把我逼疯了-_-

------------------好吧,伙计们,记住,我不是专家。

我用return再次测试,发现两个密码结果是两个完全不同的密码。

75642f23ef3c7b35d0a5e223a9c3187d102e77dcc121b5d08c7bbcb44de73e2c 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b

我不知道。花了太多时间在这个愚蠢的腌制东西上,只是想学习-_-,我想我会使用内置的哈希函数,永远不会从我的错误中吸取教训,叹息......

是的,不是每个人都有 PHP 5.5,所以我不能使用那些内置函数。

【问题讨论】:

  • 请使用password_hash代替你自己的自定义函数php.net/manual/en/function.password-hash.php
  • 使用password_hash可以省去很多麻烦
  • 为什么你在一个地方使用DatabaseHelpers::hash而在另一个地方使用一个单独的verify函数?他们不应该做同样的事情吗?
  • 我遇到了错误,所以我把它分成不同的函数来找出问题所在,但我还没有改回来。
  • 你可以说它只适用于 PHP 5.5...不是每个服务器都有 5.5...

标签: php


【解决方案1】:

您的验证功能实际上并没有任何事情。它对加盐/密码进行 sha256 哈希处理,然后简单地丢弃该哈希。由于函数中没有return,因此调用代码只需获取NULL 值。

你可能想要这样的东西:

function verify($pass, $salt) {
   return hash('sha256', $pass . $salt);
   ^^^^^^----note the return call.
}

if ($hashed_password_from_database == verify($password_from_form, $salt))

【讨论】:

  • 此外,verify() 函数实际上应该验证密码。现在,它只是散列它——这意味着它实际上并没有按照它所描述的那样做。此外,验证函数应该安全地比较哈希值,现在它容易受到基于时间的攻击。