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

Luk*_*non 1 php security crypt cryptography password-encryption

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

<?php
echo crypt("cryptcryptcrypt","salt");
echo "<br>";
echo crypt("cryptcryptcrypta","salta");
?>
Run Code Online (Sandbox Code Playgroud)

- 结果是:

saRyxun8Pn/K6
saRyxun8Pn/K6
Run Code Online (Sandbox Code Playgroud)

为什么这是hapening?


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

161*_*903 8

引用文档:

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

您提供的盐只有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";
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这需要支持SHA-512,这需要PHP 5.3.2,我觉得你使用的是旧版本.你有哪个PHP版本? (2认同)