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 安装对于任何体面的实施来说都太旧了。我强烈建议找一个支持更高版本的服务器。希望我的示例对您或其他人有所帮助,以及由于原始密码相似性而导致的推理。
我 运行 我的登录系统出现了一些问题。如果我将我的用户密码设置为 '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 安装对于任何体面的实施来说都太旧了。我强烈建议找一个支持更高版本的服务器。希望我的示例对您或其他人有所帮助,以及由于原始密码相似性而导致的推理。