由于PHP sha1()可以通过与长哈希列表进行比较而很容易被破坏 - 这会更好(基本上 - 一遍又一遍地应用sha1()以尝试通过减慢散列来强制执行不切实际的操作处理下来):
<?php
$iterations = 100000;
$pass = 'hyugf67rf76dt564d5r76';
$salt = '6t6755636459679guytfugiuhbguiygfytcdtresr5tdt5yfuybiugbuyfr56d45esertdcftyuuguy';
$hash = '';
for ($i=0; $i<$iterations;$i++) {
$hash = sha1($hash . $pass . $salt);
}
echo $salt . $hash;
?>
答案 0 :(得分:2)
不是一次又一次地应用sha1
,为什么不用强盐实施crypt()
一次呢?
如果你有PHP 5.5 +,你只需要password_hash()
还可以使用password_hash()的用户态实现here
提示:您可以将上面password_hash()
文档链接的示例#4和#3结合起来,以创建更强大的哈希值。
或使用phpass
phpass支持的首选(最安全)散列方法是 OpenBSD风格的基于Blowfish的bcrypt,也得到我们公众的支持 domain crypt_blowfish包(用于C应用程序),在PHP中已知 作为CRYPT_BLOWFISH,,回退到基于DES的BSDI风格扩展 哈希,在PHP中称为CRYPT_EXT_DES,是最后的回归 基于MD5的盐渍和变量迭代计数密码哈希值 在phpass本身中实现(也称为便携式哈希)。
答案 1 :(得分:1)
解决问题的更好方法是使用内置此成本强度的散列算法,而不是使用自定义函数。如果生成的哈希不是真正随机的,这可能是一个安全问题。
但是,这并没有回答你的问题,所以我现在尝试这样做。
<强>成本强度强>
如果应用得当,那些成本更高的算法会使攻击者破解数据库中的所有密码成本更高。如果应用不正确,可以绕过大部分成本强度。这就是为什么我建议使用设计成本密集的算法,而不是尝试自己创建一些东西。
<强>盐强>
数据库范围的盐只能在没有盐的情况下保护您免受彩虹表的影响。当攻击者使用密码获取您的数据库并且知道盐时,他们可以使用您的盐创建自己的彩虹表,并使用此彩虹表破解数据库中的每个密码。具有相同密码的用户在数据库中具有相同的哈希值。
每帐户盐(每个帐户的盐不同),攻击者必须单独破解每个密码。具有相同密码的用户在数据库中具有不同的哈希。破解密码现在成本更高。
<强>迭代强>
重新应用时应该警惕的是,攻击者不应该为此次迭代的一部分创建查找表。换句话说:迭代应该包含对每个用户都不同的东西,甚至更好,对于为用户尝试的每个密码都是不同的。由于您在算法中重复使用密码,这应该没问题。*
然而,对算法的一点改动可能允许攻击者绕过大部分迭代。在下面的代码中,攻击者可以创建一个查找表,将哈希值转换为哈希值,其中sha1应用于99.999。实际上,可以通过在每个哈希上仅应用一次,然后多次使用该查找表来创建这样的表。现在已经减少了创建一个查找表,为每个密码应用sha1一次,并在查找表中为每个密码查找一次哈希值,而不需要为每个密码应用sha1 100.000次。即使使用每用户盐,这也不会对查找表产生任何影响。
如果您要使用每用户salt并将//here
更改为sha1($hash . $salt)
,则攻击者必须为数据库中的每个唯一salt创建一个这样的表。这稍微多一些工作,但仍然比攻击者必须要为他们尝试的每个密码计算每个哈希值时要做的工作少得多。
<?php
#Bad code below
$iterations = 100000;
$pass = 'hyugf67rf76dt564d5r76';
$salt = '6t6755636459679guytfugiuhbguiygfytcdtresr5tdt5yfuybiugbuyfr56d45esertdcftyuuguy';
$hash = sha1($hash . $pass . $salt);
for ($i=0; $i<$iterations;$i++) {
$hash = sha1($hash); //Here
}
echo $salt . $hash;
?>
*我绝不是安全专家。我是一名学生,对算法有一定的了解,对安全有一些了解,但事实上我没有看到问题并不意味着没有问题。