0

我在我多次运行的 PHP 页面中有这段代码。每次我刷新页面时,盐都会改变(应该如此),但哈希输出保持不变。

$iv = mcrypt_create_iv(22);
$ro = rand(6, 9);
$salt = '$2y$'.$ro.'$'.$iv.'$';
echo $salt;
echo '<br />';
$crypt = crypt('test', $salt);
echo $crypt;

随机盐不应该影响输出并使其每次刷新页面时crypt结果也会改变吗?

我还有一些关于crypt().

有什么方法可以让你在这个函数中使用特定的散列算法?我想使用河豚算法。

盐长度/格式是否会影响它选择的算法?

最后,河豚算法的盐长度应该始终为 22 个字符,还是只是最大值?

顺便说一句,如果有人想知道(如果回答这些问题很重要并且不明显),我打算使用类似的东西来存储散列密码。

感谢您的关注!

4

1 回答 1

3

您系统上的 crypt() 函数不支持“2y”算法。至少基于 Linux GLIBC 2.7 的系统只知道 DES、$2a$ (blowfish)、$5$ (SHA-256) 和 $6$ (SHA-512)。因此,crypt() 函数假定为 DES,并且只将前两个字符“$2”作为盐。当然,这总是产生相同的输出。

尝试使用 SHA-512 获取安全密码哈希:

$salt_chars = array_merge(range('A','Z'), range('a','z'), range(0,9));
$salt = '$6$';
for($i=0; $i < 8; $i++) { $salt .= $salt_chars[array_rand($salt_chars)]; }
echo "salt=$salt\n";

$crypt = crypt('test', $salt);
echo "crypt=$crypt\n";

关于您的第二个问题,您可以通过使用例如“$2a$”(而不是上面的 $6$)作为河豚的盐来选择算法。阅读“man 2 crypt”了解详情。对于某些算法,您还可以将更多参数(例如“rounds = 4000”)编码到盐中。

根据 crypt() 手册页,salt 在 $id$ 之后最多可以有 16 个字符。较长的盐将被静默截断并产生与仅前 16 个字符相同的输出。

顺便说一句,即使在 /etc/shadow 中,密码也仅使用 SHA-512 算法的 8 个盐字符。由于盐只是为了使彩虹表攻击更难,这似乎就足够了。

于 2013-06-16T22:38:20.100 回答