Crypt为两个不同(相似)的密码返回相同的散列


Crypt returning same hash for two different (similar) passwords

我在使用crypt()时遇到问题,如果用户有密码(本例中为password1),并且他们将其更改为password2,则哈希将返回相同的结果。您可以在此处测试:旧链接输入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.";
            }
        }
    }
}
?>

要使用crypt,必须提供适当的盐。每个算法都有自己的salt格式。我的猜测是,您使用了一些随机字符作为salt,这与任何高级算法都不匹配,所以php将salt减少到前2个字符,并回退到基本的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