在密码哈希中更喜欢 bcrypt 或 PBKDF2 而不是 SHA256-crypt 的具体原因是什么?

信息安全 密码 哈希 bcrypt
2021-08-15 04:05:46

我们知道,为了在密码数据库泄漏的情况下减缓密码破解,密码应该只以散列格式保存。不仅如此,它还具有强大而缓慢的功能,可以改变轮数。

通常为此推荐使用PBKDF2bcryptscrypt等算法,bcrypt 似乎获得了最响亮的选票,例如hereherehere

但是基于 SHA256 和 SHA512 的哈希值至少在 glibc ( description , specification ) 中实现并且默认情况下至少在某些 Linux 发行版中用于常规登录帐户?是否有理由不使用它们,或者更喜欢 bcrypt 而不是基于 SHA-2 的哈希?

当然 bcrypt 明显更老(1999 年),因此更成熟,但 SHA-2 哈希到现在(2007 年)已经 9 岁了,scrypt 更年轻一点(2009 年),但似乎仍然被更多人提及经常。这只是一种公认​​的做法,还是有其他原因?基于 SHA-2 的哈希是否有任何已知的弱点,或者有人看过吗?

注意:我特别指的是链接文档中描述的多轮密码散列,并用代码$5$散列标记,而不是单轮普通的 SHA256 或 SHA512 散列函数$6$crypt

我已经看到这个被标记为可能重复的问题。答案没有提到 SHA256-crypt / SHA512-crypt 哈希,这就是我正在寻找的。

4个回答

使用特定密码散列函数的主要原因是让攻击者的生活更加艰难,或者更准确地说,是为了防止他们让自己的生活变得更轻松(与防御者相比)。特别是,攻击者可能希望通过使用 GPU 在给定预算的情况下每秒计算更多的哈希值(即每秒尝试更多的密码)。

尤其是 SHA-256,在 GPU 上实现受益匪浅。因此,如果您使用 SHA-256-crypt,攻击者将比使用 bcrypt 更有优势,而 bcrypt 很难在 GPU 中有效实现。

有关 bcrypt 与 PBKDF2 的一些讨论,请参阅此答案尽管 SHA-256-crypt 不是 PBKDF2,但它在 GPU 上的性能表现非常相似,因此适用相同的结论。

SHA-512 的情况不太清楚,因为现有 GPU 在使用 32 位整数方面比 64 位要好得多,而 SHA-512 主要使用 64 位操作。预计现代 GPU 每秒允许的哈希值比使用 SHA-512-crypt 的 CPU(对于给定的预算)更多,这再次表明 bcrypt 是更好的选择。

SHA-2 系列哈希被设计为快速。BCrypt 的设计速度很慢。两者都被认为是稳健的。如果有足够的回合或工作因素,任何一个都可能比另一个花费更长的时间,但我会倾向于设计慢的那个。(如果服务器负载是个问题,Work Factor 是可调整的)

此外,我倾向于 BCrypt,因为它通常是编译实现(C 或 C++)。

多轮 SHA 可以很容易地用高级语言实现,至少对于迭代,如果不是哈希本身也是如此。高级语言对于基本数学运算的效率较低,这会减少生产硬件每毫秒可以完成的轮数。

虽然这两种算法都可以用高级或低级语言或混合语言来实现;BCrypt中,可用的选项表明您更有可能获得有效的实施(让您与攻击者处于更公平的竞争环境中)

关于/etc/shadow文件中的具体示例,无论哪种方式,您都可能只使用低级(高效)算法。(SHA 或 BCrypt)在此示例中,我建议您查阅操作系统文档以根据硬件速度优化轮次(工作因子)-vs- 您希望散列的强度。

scrypt(具有足够大的工作系数)具有额外的好处,即具有额外的 RAM/内存要求(不仅仅是 CPU),使其比 SHA、BCrypt 或 PBKDF2更耐 GPU 。

编辑:感谢Thomas 指出 BCrypt 比 SHA-2 更耐 GPU,并且 SHA-2 和 PBKDF2 在这方面实际上是等效的

注意:在进行此编辑后,我正在查看此问题,并将其考虑在内:

注意:我特别指的是链接文档中描述的多轮密码散列,并在密码散列中标有代码 $5$ 和 $6$,而不是单轮普通的 SHA256 或 SHA512 散列函数。


查看您提供的此链接中的长 22 步算法,我宁愿提出一个问题:为什么您更愿意使用这个而不是PBKDF2和 HMAC-SHA2?因为,至少如前所述:

  • PBKDF2 的定义看起来要简单得多。 这是因为它更加模块化——它将大部分工作交给外部提供的伪随机函数。这通常使用HMAC实例化,而 HMAC又将其大部分工作交给外部散列函数,如 SHA-1 或 SHA-2。
  • 这意味着 PBKDF2 的安全性应该更容易分析。

相比之下,您提供的文档中的算法列出了大量步骤,其动机更难理解。例如:

11. For each bit of the binary representation of the length of the
    password string up to and including the highest 1-digit, starting
    from to lowest bit position (numeric value 1):

    a) for a 1-digit add digest B to digest A

    b) for a 0-digit add the password string

    NB: this step differs significantly from the MD5 algorithm.  It
    adds more randomness.

它增加了更多的随机性?它是如何做到的?为什么会存在这一步——SHA-2 是否没有增加足够的随机性?如果 SHA-2 不够随机,为什么要首先使用它?并且这一步不是在算法中引入了依赖于秘密的分支,从而引发了可能针对它的定时攻击的问题吗?

我绝不是说您链接的算法不安全。就是这样:

  • 他们引入的工作因素归结为与 PBDKF2--HMAC-SHA2 所做的相同的事情(大量的 SHA2 迭代);
  • 如果您展开 PBKDF2-HMAC-SHA2 实现,它们看起来与您所拥有的非常相似,但具有额外的复杂性,我不明白其目的;
  • 因此,至少正如那些文档中所述,我发现对他们的设计获得信心比对 PBKDF2 更难。

编辑:在我写完所有这些之后,我对这个算法做了一些研究,试图更好地理解它。首先,从问题本身的“描述”“规范”链接中,我们了解到该算法是通过进行相对较小的修改而从较旧的基于 MD5 的算法派生而来的。

这种较旧的基于 MD5 的算法似乎是 Poul-Henning Kamp 在 1994 年为 FreeBSD-2.0 编写的算法,他不再认为它是安全的。在第一个链接中(他讲述了函数的历史),他提到 glibc 也采用了他的函数。他还链接到Provos 和 Mazières 1999 年关于 bcrypt 的论文,并提到它表达了一些反对意见,有趣的是,他们强调了上面引起我注意的同一步骤

MD5 crypt以多种不同的组合对密码和盐进行哈希处理,以减慢评估速度。算法中的某些步骤让人怀疑该方案是从密码学的角度设计的——例如,密码长度的二进制表示在某个点决定了哪些数据被散列,对于每个零位,密码的第一个字节和对于每个设置位,前一个哈希计算的第一个字节。

但我认为这解释了您所询问的新功能的动机:它们是对旧功能的最小修改,该功能早于大多数现代密码哈希函数,其设计已受到质疑,但可能并未从根本上破坏,只是毫无意义的复杂。

SHA-2 系列本身并不一定不好。按照设计,实际上并没有任何安全漏洞使 bcrypt 或 scrypt 更受欢迎。然而,许多安全专家对 SHA 的问题是它太快并且不需要太多内存。相比之下,可以说,像 scrypt 这样的散列函数要慢得多且昂贵得多。

Scrypt 需要大量内存来计算。除了所有这些内存之外,主要是由于需要如此多的内存,与 SHA 相比,scrypt 需要大量的计算时间。来自比特币堆栈交换网站的这个答案很好地总结了 scrypt 的优点:scrypt() 的哪些功能使 Tenebrix GPU 具有抗性?从本质上讲,scrypt 被设计为缓慢且占用大量内存。GPU 不喜欢这样。GPU 通常没有内存容量来存储 scrypt 计算所需的所有内存,而不必诉诸执行阻塞方法(GPU 阻塞所有线程,因为它一次只能从共享内存中检索一个值),因此 GPU 在处理时间方面无法比 CPU 提供任何大的优势。Bcrypt 类似。

Bcrypt 被尝试用于密码散列。它已经存在了 17 年,它仍然可以完成工作。然而,有一天,GPU 技术将发展到能够比 CPU 更快、更有效地计算 bcrypt 的程度。技术总是在发展和发展,所以它最终会发生。当那一天到来时,bcrypt 将不再是密码散列的绝佳选择,密码学家和安全专家将需要用比现有 bcrypt 更慢且内存更密集的类似算法替换 bcrypt。也许那将是 scrypt,但谁能说。那么,为什么 SHA 不受欢迎呢?

SHA 通常不受欢迎,不是因为安全漏洞,而是因为速度及其在 GPU 上实现的能力。拥有无限机器/计算能力的人可以破解任何类型的哈希算法,无论是 SHA、bcrypt 还是 scrypt,但这是理论上的。在实践中,攻击者不会有无限数量的机器来尝试破解哈希,因此,您越能减慢攻击者的速度,他们破解密码的难度就越大。凡事都有预算限制,密码破解也不例外。攻击者只能在预算允许的范围内尽快破解密码。他们可以在预算内购买的最佳技术,运行该技术的成本(例如,电力成本)等。) 当然,您可以实施多轮 SHA 来严重减慢攻击者的速度,但为什么不在此时使用 bcrypt 呢?除此之外,随着 GPU 技术在不久的将来取得进步,您将需要在 SHA 计算中添加越来越多的轮次/迭代,以将其减慢到比 bcrypt 慢的程度。但是,随着 GPU 技术的进步,bcrypt 将保持不分阶段,直到 GPU 技术可以有效地计算 bcrypt。因此,在可能的情况下,bcrypt 是首选,不是因为 SHA 不安全,而是因为 SHA 的计算效率太高。