PHP 密码散列返回相同的值

PHP Password hashing returning the same value

我 运行 我的登录系统出现了一些问题。如果我将我的用户密码设置为 'TestPassword1234','TestPassword' 将被接受为密码。

经过更多测试后,我发现即使传递的字符串不相同.

,以下代码也会创建两个相同的哈希值

重要的是要知道所有使用的盐都是由这个函数生成的。每个测试生成一个,同一个用于散列两个字符串(就像登录用户时一样)。

function GUID() {
    if (function_exists('com_create_guid') === true) { return trim(com_create_guid(), '{}'); }

    return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}

上面的函数来源于一个栈溢出的问题,不知道是哪个。

如果从根本上更改了密码,则情况并非如此,请参见下面的测试。

以下代码片段显示了两个不同的密码产生相同的哈希值。

$guid = GUID();

echo( crypt("TestPassword1234", $guid ) ); //455nKS7NToPuY
echo("<br />");
echo( crypt("TestPassword", $guid ) ); //455nKS7NToPuY (the same!)

此代码段显示了两个不同的密码,即使它们遵循与上述代码段类似的模式,但不会产生相同的结果

$guid = GUID();

echo( crypt("Test1234", $guid ) ); //BBWxwWzIXAOQI
echo("<br />");
echo( crypt("Test", $guid ) ); //BBhe4TjDcO5XA (different...)

我假设问题源于使用 GUID 函数。可能是错误的或者只支持最大长度为 x 的密码。我不知道也无法找到我在上面找到的 SO 问题。

非常感谢您的帮助。

要使用 crypt(),您必须遵守手册中列出的算法盐格式之一。您没有遵循其中一种格式,因此 PHP 将盐分减少到前两个字符,并使用 DES 算法对其进行计算。 DES 仅使用前 8 个字符,因此您仅使用相同的盐对 "TestPass" 进行两次哈希处理。

最好的做法是使用 password_hash() instead. However, as you mentioned your host does not support password_hash()

如果 crypt() 是最终选择,那么您将需要正确格式化 salt。但是,使用 crypt() 选择的最佳算法只允许最多 16 个字符用于盐。由于大部分数据未被使用,因此使用 GUID 并不是最佳选择。

这是一个使用安全随机字节生成器的示例,这仅适用于 PHP 5.3.2 及更高版本:

function newSalt() {
    $salt = bin2hex(openssl_random_pseudo_bytes (8));
    return '$'.$salt;
}


$salt1 = newSalt();
$salt2 = newSalt();

echo( crypt("TestPassword1234", $salt1 ) );
echo("<br />");
echo( crypt("TestPassword", $salt2 ) );

您可以通过存储 newSalt() 生成的值来存储盐以备后用

编辑: OP 的 PHP 安装对于任何体面的实施来说都太旧了。我强烈建议找一个支持更高版本的服务器。希望我的示例对您或其他人有所帮助,以及由于原始密码相似性而导致的推理。