对于不同的字符串和salt,PHP .crypt()结果相同

时间:2016-02-26 07:35:22

标签: php security cryptography password-encryption crypt

因为我使用的是旧版本的PHP,所以我必须使用.crypt()。我正在测试一些密码验证,服务器验证错误的密码是正确的。然后我决定尽可能进行最基本的测试,我仍然有这个问题:

<?php
echo crypt("cryptcryptcrypt","salt");
echo "<br>";
echo crypt("cryptcryptcrypta","salta");
?>

- 结果是:

saRyxun8Pn/K6
saRyxun8Pn/K6

为什么这是hapening?

出于测试目的,我使用PhpFiddle,因此您在回答时可能会觉得这很有用......

1 个答案:

答案 0 :(得分:8)

引用docs

  

标准的基于DES的crypt()返回salt作为输出的前两个字符。它也只使用str的前八个字符,所以较长的字符串以相同的八个字符开头将产生相同的结果(当使用相同的盐时)。

您提供的盐只有4或5个字符长,这使得crypt使用标准的基于DES的算法。因此,仅使用密码的前9个字符,并且仅使用前两个字符的盐。因此你的哈希是平等的。你真的应该更新你的PHP版本,这样你就可以使用现代的password_hash函数。如果无法做到这一点,请尝试使用与PHP 3及更高版本兼容的http://www.openwall.com/phpass/。如果不能阅读......

您需要将正确格式的salt传递给crypt函数。从文档中的示例:

if (CRYPT_BLOWFISH == 1) {
    echo 'Blowfish:     ' . crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') . "\n";
}

if (CRYPT_SHA256 == 1) {
    echo 'SHA-256:      ' . crypt('rasmuslerdorf', '$5$rounds=5000$usesomesillystringforsalt$') . "\n";
}

if (CRYPT_SHA512 == 1) {
    echo 'SHA-512:      ' . crypt('rasmuslerdorf', '$6$rounds=5000$usesomesillystringforsalt$') . "\n";
}

哈希的开头定义了要使用的算法。您还需要确保为每个用户使用随机唯一盐。