PHP密码哈希返回相同的值

时间:2016-05-14 05:15:40

标签: php password-hash

我遇到了登录系统的一些问题。如果我将用户密码设置为' 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问题。

非常感谢帮助。

1 个答案:

答案 0 :(得分:3)

要使用crypt(),您必须遵守手册中列出的算法盐格式之一。您没有遵循其中一种格式,因此PHP会将您的盐减少到前两个字符,并使用DES算法进行计算。 DES仅使用前8个字符,因此您只需要散列&#34; TestPass&#34;用同样的盐两次。

更好的办法是改用password_hash()。但是,正如您所提到的,您的主机不支持password_hash()

如果crypt()是最终选择,那么您需要正确格式化盐。但是,使用crypt()进行选择的最佳算法仅允许盐最多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的安装都太旧了。我强烈建议找一个支持更高版本的服务器。我希望我的例子可以帮助你或其他人,以及由于原始密码的相似性而导致的推理。