密码加密返回相同的哈希值,即使密码不同(但相似)。

5
我在使用crypt()时遇到了一个问题:如果用户的密码(例如本例中的password1)更改为password2,则哈希会返回相同的结果。您可以在这里进行测试:OLD LINK,将当前密码输入为password1,新密码和确认密码同时输入password2,然后查看结果。如果输入完全不相似的密码,则没有问题。我知道有其他方法来哈希密码等等,但我只是好奇。以下是我的代码:
<?php

$oldpassword="password1";

echo "<form method=\"post\">
<p>Enter Current Password: <input type=\"password\" name=\"currentpassword\" /></p>
<p>Enter New Password: <input type=\"password\" name=\"password\" /></p>
<p>Confirm New Password: <input type=\"password\" name=\"confirmpassword\" /></p>
<p><input type=\"submit\" value=\"Change Password\"></p>
</form>";

$user_id = $_SESSION['user_id'];
$pass=$_POST['password'];
$salt = 'xxxxx';
$currentpassword = crypt($_POST['currentpassword'], $salt);
$oldpassword = crypt($oldpassword, $salt);
if(isset($_POST['password'])) {
    if ($currentpassword !== $oldpassword) {
        echo "The password you entered for current password does not match our records.";
    }
    else {
        if ($_POST['password'] && $_POST['confirmpassword']) {
            if ($_POST['password'] == $_POST['confirmpassword']) {
            $hash = crypt($pass, $salt);
                if ($hash == $currentpassword) {
                    echo "Current Password:&nbsp;";
                    var_dump($_POST['currentpassword']);
                    echo "<br/>";
                    echo "New Password:&nbsp;";
                    var_dump($_POST['password']);
                    echo "<br/>";
                    echo "New Hash:&nbsp";
                    var_dump($hash);
                    echo "<br/>";
                    echo "Current Password Hash:&nbsp";
                    var_dump($currentpassword);
                    echo "<br/>";
                    echo "<hr/>";
                    echo "Your new password cannot be the same as your current password.";
                }
                else {
                    echo "Your password has been changed successfully<br/>";
                }
            } else {
                echo "Your passwords do not match. Please try again.";
            }
        }
    }
}

?>

1
你使用的是哪个crypt()算法? - TML
2
@TML,似乎限制字符串长度为7个字符。而Kevin,你不应该自己编写此代码。使用 password_hash 或在评论中提到的与之兼容的Github兼容包(适用于 PHP < 5.5)即可实现向前兼容。 - Mike
1
是的,password_hash()也是我要建议的;我打赌使用了DES。 - TML
2
@KevinO'Brien 这就是为什么我在评论中提到了 Github 链接。它与 PHP >= 5.3.7 兼容。 - Mike
@KevinO'Brien,我不确定你的意思。如果是随机的话,当您重新加密时盐值将不同。您希望每次都不同。使用bcrypt时,盐值直接存储在哈希中,因此您无需重新生成它来验证密码。 - Mike
显示剩余7条评论
1个回答

13
要使用crypt,您必须提供正确的salt。每个算法都有自己的salt格式。我猜你正在使用一些随机字符作为salt,这不符合任何高级算法,因此php将您的salt缩减到前两个字符,并回退到基本的DES算法。DES算法最多可以哈希8个字符,而password1password2都是9个字符长,因此只有password从两者中使用,因此哈希相同。
解决方案:为最强可用算法使用正确的salt格式,为每个密码生成随机salt。
推荐解决方案:https://github.com/ircmaxell/password_compat(适用于php 5.3.7-5.4.x),并在切换到php 5.5之后使用http://php.net/password_hash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接