0

我已经注册了一个新用户,并使用以下散列方法将用户名、密码和盐保存在数据库中:

    if(isset($_POST['register']))
    {
    $password = $_POST['password']

    function sanitize($data)
    {
        $data=trim($data);
        $data=htmlspecialchars($data);
        $data=mysql_real_escape_string($data);
        return $data;
    }

    $password = sanitize($password);

    function createSalt()
    {
        $salt = bin2hex(mcrypt_create_iv(32,MYCRYPT_DEV_URANDOM));
        $hash = hash("sha256", $salt);
        $final = $salt.$hash;
        return $final;
    }

    $hashedPassword = hash("sha256", $password);
    $salt = createSalt();
    $hashedPassword = hash("sha256", $hashedPassword.$salt);

    $query = sprintf("INSERT INTO users(username, password, salt) VALUES('%s','%s','%s')",$username, $hashedPassword, $salt);
}

稍后在尝试 login.php 时,我输入了注册时保存的相同密码,并使用以下代码检查输入的密码是否与数据库中的密码相同

if(isset($_POST['login']]))
{
            $password = $_POST['password']

    function sanitize($data)
    {
        $data=trim($data);
        $data=htmlspecialchars($data);
        $data=mysql_real_escape_string($data);
        return $data;
    }

    function validateUser()
    {
        session_regenerate_id (); //this is a security measure
        $_SESSION['valid'] = 1;
        $_SESSION['username'] = $username;
    }

    $password = sanitize($password);

    $query = sprintf("SELECT * FROM users WHERE username = '%s'",$username);
    $sql = mysql_query($query);
    $count = mysql_num_rows($sql);

    $row = mysql_fetch_array($sql);

    if($count<1)
    {
        echo $count;
        unset($_POST['login']);
        header("location:login.php");
        exit;
    }

    $hash = hash("sha256", $password);
    $salt = $row['salt'];
    $hash = hash("sha256",$hash.$salt);

    echo $hash."<br />".$row['password']."<br /><br />";

    if($hash != $row['password'])
    {
        unset($_POST['login']);
        header("location:login.php");
        exit;   
    }
    else
    {
        validateUser();
        unset($_POST['login']);
        header("location:index.php");
        exit;   
    }
}

这些密码不匹配。请让我知道这段代码有什么问题。

4

2 回答 2

0

您的代码没有任何问题。

存储在数据库中的 salt 值被截断,因为 varchar 值很低,将 salt 列的 varchar 值增加到 200-300 左右,然后试试这个.. 它会运行良好。

当我发现这搞砸了结果时,我捂住了脸。

丁斯

于 2012-11-09T08:31:58.913 回答
0

实际上我不明白为什么这不起作用,您显示的代码应该产生相同的值,也许您可​​以检查一下,您从数据库中读取的盐是否真的与您写入数据库的相同。

尽管如此,我不鼓励在这条路线上走得更远,这里有很多问题。

  1. 首先,SHA-256 不是哈希密码的好选择,而是使用像BCrypt这样的慢速密钥派生函数。
  2. 您不应该在没有必要的情况下转义输入数据,如果您需要转义它们,您应该只针对特定的目标系统进行转义(如果您要计算哈希,则没有任何意义)htmlspecialcharsmysql_real_escape_string
  3. 要创建盐,您可以使用随机源,这很好。在创建盐之后使用散列,绝不会使盐更随机。
  4. 数据库中不需要密码和盐两个单独的字段。Php 的crypt()函数将创建一个已经包含盐的哈希值。

我会邀请你阅读这篇关于散列密码的教程,你也会找到一个 PHP 示例,我建议使用phpass库。

于 2012-11-09T08:33:36.727 回答