我已经长时间使用了无盐的md5 / sha1,但由于这种方法不太安全(并且随着时间的推移变得越来越不安全)我决定切换到盐渍的sha512。此外,我想通过使用多次迭代(例如100)来减慢散列的生成。
我的问题是我是应该在每次迭代时添加盐还是在开始时只添加一次。以下是两个可能的代码:
每次都附加:
// some nice big salt
$salt = hash($algorithm, $salt);
// apply $algorithm $runs times for slowdown
while ($runs--) {
$string = hash($algorithm, $string . $salt, $raw);
}
return $string;
追加一次:
// add some nice big salt
$string .= hash($algorithm, $salt);
// apply $algorithm $runs times for slowdown
while ($runs--) {
$string = hash($algorithm, $string, $raw);
}
return $string;
我首先想要使用第二个版本(追加一次)但是每次都会找到一些附加盐的脚本。
所以,我想知道每次添加它是否会增加哈希的强度。例如,攻击者是否有可能找到一种聪明的方法来创建一个100xSha512函数,这比简单地执行sha512 100倍?
答案 0 :(得分:51)
简而言之:是的。转到第一个例子......如果反馈给自己而不添加原始数据,哈希函数可能会丢失熵(我现在似乎无法找到引用,我会继续查看)。
为了记录,我支持多次哈希。
生成需要500毫秒的哈希对于您的服务器而言并不太慢(考虑到生成哈希值通常不会在绝大多数请求中完成)。然而,花费那么长的哈希将显着增加生成彩虹表所需的时间......
是的,它确实暴露了DOS漏洞,但它也可以防止暴力攻击(或至少使它们过于缓慢)。绝对是一种权衡,但对某些人来说,这些好处超过了风险......
整个过程的引用(更像是概述):Key Strengthening
至于退化的碰撞,我到目前为止找到的唯一来源是this discussion ......
关于这个主题的更多讨论:
还有一些链接:
有很多结果。如果你想要更多,谷歌hash stretching
......那里有很多好消息......
答案 1 :(得分:6)
除了多次重新哈希之外,我还会为每个密码/用户使用不同的盐。虽然我认为5000次迭代有点过多,但请尝试使用较低的数字。这里有一个权衡;你必须根据你的需要和硬件调整它。
对于每个密码使用不同的盐,攻击者将被迫单独强制使用每个密码,而不是构建彩虹表,这会大大增加工作量。
与往常一样,这是推荐阅读:Just hashing is far from enough
编辑:迭代哈希是perfectly valid tactic。有权衡,但一切都有它们。如果您担心计算时间,为什么不直接存储明文密码?
答案 2 :(得分:3)
请不要滚动你自己的加密。这就像OpenSSL这样的库。以下是一些很好的例子,说明如何使用它来制作盐渍哈希。
答案 3 :(得分:0)
迭代散列的原因是使进程尽可能慢。所以你可以做得更好:每次迭代使用不同的盐。可以通过使用固定密钥和使用盐值进行异或来在每次迭代中反复加密原始数据来完成。
答案 4 :(得分:0)
我更喜欢使用带有两种不同盐的双sha1,并且防止DoS每次无效密码检查都会逐步延迟(简单的使用)。