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(),您必须遵守手册中列出的算法salt格式之一。您没有遵循其中一种格式,因此PHP将您的salt减少到前两个字符,并使用DES算法进行计算。DES只使用前8个字符,因此您只能用相同的salt对"TestPass"进行两次哈希处理。

最好使用password_hash()。但是,正如您所提到的,您的主机不支持password_hash()。

如果crypt()是最终选择,则需要正确格式化salt。然而,crypt()的最佳算法只允许salt最多包含16个字符。因此,使用GUID不是最佳选择,因为大多数数据都未使用。

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

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

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

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

编辑:OP的PHP安装太旧,不适合任何像样的实现。我强烈建议找一个支持更高版本的服务器。我希望我的例子能帮助到你或其他人,以及由于原始密码相似性而进行的推理。