【发布时间】:2011-12-22 09:02:22
【问题描述】:
一段时间以来,我一直在寻找一种更安全的方法来对我的网站上的用户密码进行哈希处理,以将其插入数据库。我研究了所有可用的散列方法。据说 bcrypt 是最好的,因为它很慢。我在想,如果我不需要最高的安全性,但仍然保持安全。如果我在该哈希上使用 sha512 然后使用 md5 会怎样。如果我颠倒散列的顺序有关系吗?请记住,我将为每个操作使用单独的盐。这会有多安全?是否有其他组合可以做到这一点?
【问题讨论】:
一段时间以来,我一直在寻找一种更安全的方法来对我的网站上的用户密码进行哈希处理,以将其插入数据库。我研究了所有可用的散列方法。据说 bcrypt 是最好的,因为它很慢。我在想,如果我不需要最高的安全性,但仍然保持安全。如果我在该哈希上使用 sha512 然后使用 md5 会怎样。如果我颠倒散列的顺序有关系吗?请记住,我将为每个操作使用单独的盐。这会有多安全?是否有其他组合可以做到这一点?
【问题讨论】:
您发明的任何自定义方法都更有可能存在使您的存储方法易受攻击的细微错误。这不值得付出努力,因为您不太可能发现这些细微的错误,直到为时已晚。最好使用经过试验和测试的东西。
通常,这些是您在存储密码时的选择,
第一种方法很简单,用bcrypt就行了。它几乎支持任何语言,并且已被广泛使用和测试以确保其安全性。
第二种方法要求您使用通用哈希函数(SHA-2 系列或更好,而不是 MD5 或 SHA-1,如 they're broken/weak)或更好的 HMAC,为用户创建唯一盐和一个独特的应用程序范围的盐,然后多次迭代哈希函数(100,000 等)以减慢它的速度(称为key stretching/strengthening)。
例如(伪代码)
sofar = hash("sha512", user_salt + site_salt + input_password);
iterations = 100000; // Should be changed based on hardware speed
while (iterations > 0)
{
sofar = hash("sha512", user_salt + site_salt + sofar);
iterations--;
}
user.save("password", "$sha512$" + user_salt + "$" + iterations + "$" + sofar);
每次迭代都应依赖于前一次迭代,因此无法并行化蛮力方法来破坏它。同样,应根据硬件的速度更改迭代次数,以使过程足够慢。在密码哈希方面越慢越好。
总结
使用bcrypt。
【讨论】:
我根本看不出使用 MD5 的意义。它坏了。但多轮显然更强。然而,两轮的改进不太可能有太大的不同。多次应用 SHA512 会更好。
如果您还没有这样做,您应该查看用户密码长度并加盐密码
Is "double hashing" a password less secure than just hashing it once? 提供了对多轮算法的详细评论。
实际上,我怀疑被破解的 SHA-512 密码数量很少,还有更重要的事情需要担心,比如首先防止他们看到密码 - 确保您的系统免受 SQL 注入、特权升级等。
【讨论】: