我们知道,在密码数据库泄漏的情况下,要减慢密码破解的速度,密码只能以散列格式保存。不仅如此,而且具有强大而慢速的散列功能,并可能改变轮数。

为此,通常推荐使用PBKDF2,bcrypt和scrypt之类的算法,其中bcrypt似乎最响亮投票,例如这里,这里和这里。

但是,至少在glibc(描述,规范)中实现并至少在某些Linux发行版中用于常规登录帐户的基于SHA256和SHA512的哈希又如何呢?是否有某些原因不使用它们,或者比基于SHA-2的哈希更喜欢bcrypt?

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

注意:我专门指的是链接文档描述的多轮密码哈希,并在$哈希中标记了代码$crypt,而不是单轮的普通SHA256或SHA512哈希函数。

我已经看到了这个问题标记为可能的副本。那里的答案没有提到我正在寻找的SHA256-crypt / SHA512-crypt哈希。

评论

如何安全地散列密码的可能重复项?

没有大量回合并且不占用大量内存的散列中的“弱点”是它们在GPU /专用硬件中的速度或易于实现的程度。您是否阅读了链接的答案?他们比我能给你的任何答案都要好。

@Oasiscircle,好吧,我链接到的规范指出:“两种算法的默认轮数均为5,000。”和“ N的最大值= 999,999,999”。如果与bcrypt相比,这还不够重要,那么我很乐意将其作为答案。

SHA函数不像Blowfish(这是bcrypt的构建对象)那样占用大量内存,因此可以在GPU /专用硬件中更轻松地并行化。这就是为什么与SHA进行更多回合比进行bcrypt进行较不重要的原因要小得多。旁注,我无法从当前位置查看您的规格文档。

@ilkkachu不,迭代哈希还不够好。攻击者可以在GPU上并行运行SHA并获得显着的加速。 SHA也用于比特币挖矿,因此有很多ASIC可以对其进行暴力破解。

#1 楼

使用特定密码哈希函数的主要原因是使攻击者的生活更艰难,或更准确地说,是防止他们使自己的生活更轻松(与防御者相比)。特别是,攻击者可能想要通过使用GPU在给定的预算下每秒计算更多的哈希(即,每秒尝试更多的密码)。特别是SHA-256,从中受益匪浅在GPU上实现。因此,如果您使用SHA-256-crypt,则与使用bcrypt相比,攻击者将更具优势,而bcrypt在GPU中难以有效实现。

有关bcrypt的一些讨论,请参见此答案。与PBKDF2。尽管SHA-256-crypt不是PBKDF2,但是它在GPU上的性能表现也足够相似,因此得出相同的结论。

SHA-512的案例还不太清楚,因为现有的GPU非常多与使用64位相比,使用32位整数更好。SHA-512主要使用64位操作。仍然可以预期,对于SHA-512-crypt,现代GPU每秒允许的散列数大于CPU(对于给定的预算),这再次表明bcrypt是更好的选择。

评论


“尽管SHA-256-crypt不是PBKDF2,但它在GPU上的性能表现十分相似,因此得出相同的结论。” -这正是我想要的。

–ilkkachu
16年8月11日在15:26

对于蛮力攻击,可以通过在密码中仅添加一个字符来补偿。并且已经由两个字符进行了超补偿。

–neverMind9
19 Mar 9 '19 at 5:31

#2 楼

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

此外,我倾向于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在这方面实际上是等效的。

评论


必须注意,scrypt使用可配置的内存量,具体取决于它必须完成的速度。如果您在繁忙的身份验证服务器上使用scrypt,并且必须在不到5毫秒左右的时间内计算出密码哈希,那么scrypt不能使用过多的RAM,因此与bcrypt相比,其GPU抵抗力较低。 Scrypt实际上是用于硬盘加密的(因此需要1到5秒的计算时间);它不一定适用于所有其他情况。这实际上是促使密码哈希竞赛的原因。

–托马斯·波宁(Thomas Pornin)
16年8月9日在12:14

我认为实现细节与算法的相对优点问题有点不同,它们也将取决于系统。例如在OpenBSD上,系统的libc很可能会支持$ 2y $,但在所有Linux上并非如此。至于流行的编程语言的库,我希望它们具有支持的任何(密码)哈希的C实现,但是我不确定是否需要检查。

–ilkkachu
16年8月11日在15:43

您的问题“是否有某些理由不使用它们”部分与它的实施水平有很大关系。 SHA-256并非被设计为“密码哈希”,因此,语言特定的库可能不那么被迫在本机C中实现它。这也使某些没有正确设置编译器的用户更容易安装。对于开发人员来说,编写自己的迭代也是很诱人的。我喜欢在答案中包含实施细节,以防止将来的访问者下结论。

–布莱恩·菲尔德(Bryan Field)
16年8月11日在19:14

#3 楼

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

注意:我的意思是指链接文档描述并标记有代码的多轮密码哈希$ 5 $和$ 6 $的crypt哈希值,而不是普通的SHA256或SHA512哈希函数的单轮回合。


在您提供的此链接中,我使用了长达22个步骤的算法,宁愿绕开一个问题:为什么您更希望将其与HMAC-SHA2一起使用而不是PBKDF2?因为,至少如所陈述的那样: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散列了密码和盐。许多不同的组合会减慢评估速度。算法中的某些步骤令人怀疑该方案是从密码学角度设计的,例如,密码长度的二进制表示在某个点确定要散列的数据,对于密码的第一个字节,每个零位,以及对于每个设置位,以前的哈希计算的第一个字节。

但是我认为这可以解释您所要求的较新功能的动机:它们是对较早功能的最小修改,而较早的功能密码散列函数中的一个,它的设计曾受到质疑,但可能不会从根本上被破坏,只是毫无意义的复杂。

评论


我也想知道有点,复杂的结构,尽管我们不得不问一下作者。感谢您实际解决我所指的功能,我开始感到比我想象的要陌生。就像我说的那样,它是某些Linux系统的默认密码哈希,因此我没有选择使用它本身,但是它使更多的了解变得有些有趣。 (出于某种原因,您引用的注释从一开始就是问题所在。)

–ilkkachu
16年8月8日在23:10

@ilkkachu:我已经用一些您可能有兴趣阅读的其他材料更新了我的答案。

–路易斯·卡西利亚斯(Luis Casillas)
16年8月11日,0:09

#4 楼

SHA-2家庭本身并不一定是坏事。从设计上讲,实际上并没有任何安全缺陷可以使bcrypt或scrypt更可取。但是,许多安全专家使用SHA的问题是它速度太快并且不需要太多内存。相比之下,可以说像scrypt之类的哈希函数要慢得多且昂贵。

Scrypt需要相当数量的内存才能进行计算。除了所有这些内存外,很大程度上是由于需要如此多的内存,与SHA相比,scrypt需要大量的计算时间。来自BitCoin Stack Exchange网站的答案很好地总结了scrypt的优点:scrypt()的哪些功能使Tenebrix的GPU更具抵抗力?本质上,scrypt被设计为速度慢且占用大量内存。 GPU不喜欢这样。 GPU通常没有存储容量,无法存储scrypt计算所需的所有内存,而不必诉诸执行阻止方法(GPU阻止所有线程,因为它一次只能从一个共享内存中检索值),因此,因此,就处理时间而言,GPU不能提供比CPU大的好处。 Bcrypt与之类似。

尝试使用Bcrypt对密码哈希进行验证是正确的。它已经存在了17年,并且仍然可以完成工作。但是,有一天,GPU技术将发展到可以比CPU更快,更高效地计算bcrypt的地步。技术一直在发展和发展,因此最终会发生。那天到来时,bcrypt将不再是密码散列的理想选择,密码学家和安全专家将需要用比现有bcrypt慢且占用更多内存的类似算法替换bcrypt。也许这将是秘密的,但该说谁呢。那么,为什么SHA会皱眉呢?

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

评论


scrypt和sha256crypt是完全分开的东西。

–斯蒂芬·托瑟(Stephen Touset)
16年8月9日在1:24



sha56crypt和(迭代的)sha256也有很大的不同。 libc使用的sha256crypt很乱

–eckes
19年3月7日在9:56

#5 楼

bcrypt的功能之一是算法速度很慢。这种缓慢性为暴力攻击提供了额外的安全性。但是出于同样的原因,它可能不是最好的解决方案,例如对于频繁使用的Web服务器,因为在这里,一台收费高昂的计算机将在每次登录时都要进行大量的计算。

正如您的系统可以接受的那样,额外的时间实际上会打扰暴力攻击者。

评论


sha256crypt也是一个缓慢的哈希。

–斯蒂芬·托瑟(Stephen Touset)
16年8月9日在1:24

为什么有人会设计慢的密码算法(河豚)

–eckes
17年4月29日在2:44

@eckes这是Blowfish的关键调度,它很慢,而不是其余的密码。密钥时间表是每次使用新密钥时都会产生的一次性设置成本,大约相当于521次加密。 bcrypt的作用是提取该密钥计划并对其进行一些修改,使其作为KDF更加有用。

–森林
19 Mar 7 '19 at 8:57