bcrypt和多次哈希之间有什么区别?

16

bcrypt相较于其他加密方式,更加强大

def md5lots(password, salt, rounds):
    if (rounds < 1)
        return password
    else
        newpass = md5(password + salt)
        return md5lots(newpass, salt, rounds-1)

我觉得,鉴于它的炒作,比我更聪明的人已经发现bcrypt比这个更好。有人能用“智商一般”的话解释一下区别吗?


1
bcrypt中的轮数是2^i,因此它呈指数增长,但是,非常好的问题...在相关的注释中,将bcrypt与HMAC哈希进行“额外加固”的比较是很有趣的。 - user166390
5个回答

6
主要区别在于 - MD5和其他设计用于验证数据的哈希函数被设计为快速,而bcrypt()则被设计为缓慢。
当您验证数据时,您需要速度,因为您希望尽快验证数据。
当您试图保护凭据时,速度会对您产生负面影响。攻击者拥有密码哈希副本后将能够执行更多的暴力攻击,因为MD5和SHA1等算法执行起来很便宜。
相比之下,bcrypt是故意昂贵的。这对于真正用户进行一两次身份验证时影响不大,但对于暴力破解则要花费更多的代价。

4
bcrypt和多次使用MD5进行哈希有三个显著的区别:
  1. 输出大小:MD5为128位(16字节),bcrypt为448位(56字节)。如果您在数据库中存储了数百万个哈希值,则必须考虑这一点。
  2. MD5容易发生冲突和预像攻击。
  3. Bcrypt可以配置成随着CPU变得越来越强大而迭代更多次数。
因此,使用MD5进行盐和拉伸不如使用bcrypt安全。通过选择比MD5更好的哈希函数,可以解决此问题。
例如,如果选择SHA-256,则输出大小将为256位(32字节)。如果可以像bcrypt那样配置盐和拉伸以增加迭代次数,则两种方法之间没有区别,除了存储结果哈希所需的空间量。

如果您使用bcrypt具有预先哈希的密码(工作因素12),并将工作因素增加到14,那么您是否必须重置密码?或者可以在已知工作因素的情况下重新哈希已经哈希的密码。 - David Colwell
好的,忘记MD5吧,那不是我的问题的重点。在我的示例程序中假设一个任意长度与bcrypt输出相同的哈希值。第一点已经被排除了。第三点也被排除了,因为我上面的示例解决了这个问题(通过重复哈希来增加CPU时间)。第二点仍然存在:假设有一个更好的哈希算法,那么是什么使得bcrypt更好呢? - Luke has no name
@luke 如果你可以配置盐和拉伸的迭代次数,那就最好不过了。 - Jérôme Verstrynge
看一下bcrypt的输出。在分隔符美元符号后的前21个字节中,有一个128位的盐(以base64编码),然后是184位哈希值,这是通过使用您的输入字符串作为初始密钥(尽管密钥会被多次更新)对192位字符串“OrpheanBeholderScryDoubt”进行加密得到的结果。这56个字节(448位)来自最大输入大小最初被指定为56个字节,包括尾随的\0(即使初始密钥可以长达72个字节)。 - dr jimbob
请参见:http://blog.rongarret.info/2011/06/possible-flaw-in-open-source-bcrypt.html 或者ThomasPornin在这里谈论bcrypt:http://security.stackexchange.com/a/31846/2568。(请注意,虽然他们打算让bcrypt具有192位的输出,但是一个off-by-one错误截断了密文的最后一个字节。) - dr jimbob

2
尽管这个问题已经有了答案,但我想指出BCrypt和您的哈希循环之间的微妙差异。我将忽略弃用的MD5算法和指数成本因素,因为您可以在问题中轻松改进它。
您正在计算哈希值,然后使用结果计算下一个哈希值。如果您查看BCrypt的实现,您会发现每次迭代都使用结果哈希值以及原始密码(密钥)。
Eksblowfish(cost, salt, key)
  state = InitState()
  state = ExpandKey(state, salt, key)
  repeat (2^cost)
    state = ExpandKey(state, 0, key)
    state = ExpandKey(state, 0, salt)
  return state

这就是为什么你不能拿到一个Bcrypt加密的密码,然后继续进行迭代,因为你必须知道原始密码。我无法证明,但我认为这使得Bcrypt比简单的哈希循环更安全。


2
你在有效地谈论实现PBKDF2或基于密码的密钥派生函数。实际上,它与BCrypt是一样的,优势在于可以增加派生密码所需的CPU时间。相比于BCrypt,它的优点是,通过知道密码经过了多少“迭代”,当你需要增加迭代次数时,你可以这样做而不必重置数据库中的所有密码。只需让算法获取最终结果,就好像它是在第n个迭代(其中n是前一个迭代计数)时进行的,并继续进行即可!
建议使用适当的PBKDF2库,而不是自己创建,因为正如所有加密技术一样,你只有通过互联网的“测试”才能确定其安全性(请参见此处)。
使用此方法的系统: .NET已经实现了一个库。请在这里查看。 Mac、Linux和Windows文件加密使用许多迭代(10,000+)版本的此加密方法来保护其文件系统。 Wi-Fi网络通常使用此加密方法进行安全保护。 来源 谢谢你的提问,这迫使我研究了我用于保护密码的方法。
TTD

1

严格来说,bcrypt 实际上加密文本:

OrpheanBeholderScryDoubt

64 次。

但是它是用从您的密码和一些随机生成的盐派生的密钥来执行此操作的。

密码散列不是散列

“密码散列算法”(如bcrypt)的真正优点在于它们使用大量RAM。

SHA2被设计为快速运行。如果您是实时Web服务器,并且想要验证文件完整性,则需要运行非常快,资源使用率非常低的东西。这与密码散列的相反。

  • SHA2旨在快速运行
  • SHA2可以使用128字节的RAM
  • SHA2易于在硬件中实现
  • 我拥有一个USB存储设备,可以每秒计算 330百万 哈希
  • 实际上,我拥有17个

如果您多次执行"快速"哈希(例如,PBDKF2的常见建议为10,000次),那么您实际上并没有增加任何安全性。

您需要的是一种难以在硬件上实现的哈希。您需要的是一种难以在GPU上并行化的哈希。

在过去的几十年中,我们已经了解到RAM是减缓密码哈希尝试的关键。定制硬件擅长执行原始计算(事实上,您的CPU仅有1%用于计算 - 其余用于将机器指令转换为更快的内容;预取、乱序执行、分支预测、高速缓存)。阻止定制硬件的方法是使算法必须触及大量RAM。

  • SHA2:128字节
  • bcrypt:4 KB
  • scrypt(可配置):LiteCoin中的16 MB
  • Argon2(可配置):文档示例中的64 MB

密码哈希不意味着仅仅多次使用快速哈希。

  • 现代推荐的bcrypt成本因素为12;因此计算大约需要250毫秒。
  • 要在现代单核CPU上达到这个 时间成本 ,您需要执行约330,000次SHA2迭代。

但是,我们回到我的2.5W、USB、SHA2驱动器和它的330 Mhashes/sec。为了防御它,需要进行83M次迭代。

  • 如果你尝试只添加CPU成本:你会失败。
  • 您必须添加内存成本。

bcrypt已经有21年历史了,它只使用4KB。但它仍然比任何数量的MD5、SHA-1或SHA2哈希功能都好得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接