散列/腌制时密码不匹配

时间:2012-07-05 07:48:26

标签: php mysql hash passwords salt

好的,所以下面的所有代码都不是我自己的。我一直在关注互联网上的教程,但是当我尝试运行它时,没有密码似乎匹配。我相信在输入密码时可能会出现错误,因为数据库中的内容远不及login.php脚本中描述的64个字符。我不知道。代码如下:

register.php

// Create a 256 bit (64 characters) long random salt
// Let's add 'something random' and the username
// to the salt as well for added security
$salt = hash('sha256', uniqid(mt_rand(), true) . 'something random' . strtolower($username));

// Prefix the password with the salt
$hash = $salt . $password;

// Hash the salted password a bunch of times
for ( $i = 0; $i < 100000; $i ++ )
{
    $hash = hash('sha256', $hash);
}

// Prefix the hash with the salt so we can find it back later
$hash = $salt . $hash;

// carry on with registration code...

的login.php

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

$con = mysql_connect("localhost", "redacted", "redacted", "redacted");

$sql = '
    SELECT
        `password`
    FROM `users`
        WHERE `email` = "' . mysql_real_escape_string($email) . '"
    LIMIT 1
    ;';

$r = mysql_fetch_assoc(mysql_query($sql));

// The first 64 characters of the hash is the salt
$salt = substr($r['password'], 0, 64);

$hash = $salt . $password;

// Hash the password as we did before
for ( $i = 0; $i < 100000; $i ++ )
{
    $hash = hash('sha256', $hash);
}

$hash = $salt . $hash;

if ( $hash == $r['password'] )
{
    session_start();
    header('Location: /quiz/index.php');
}

if( $hash != $r['password'] ){
    session_start();
    header('Location: /?error=4');
}

// end login script

2 个答案:

答案 0 :(得分:2)

常见错误是数据库字段的长度不足以存储所有字符。密码将永远不会与用户输入的内容相同。

对于这种功能,请始终编写单元测试,以检查功能(静止)是否按预期工作。有一天,有人会修改数据库,更改哈希算法,修改盐...并且没有人能够登录。

答案 1 :(得分:-1)

看起来你要加盐2次:

$hash = $salt . $password;

// Hash the password as we did before
for ( $i = 0; $i < 100000; $i ++ )
{
    $hash = hash('sha256', $hash);
}

//skip the below one
$hash = $salt . $hash;

<强>更新

实际上,在这种情况下需要添加盐2次。

虽然,salt应该保存在一个单独的db列中,因此代码将更加简化 - 通过避免存储/检索salt的所有字符串连接。

除此之外,通过将每条信息存储在一个单独的插槽中,您的数据库结构将更接近第三范式