SHA-1是否安全存储密码?


148

结论: SHA-1与任何其他对原像攻击的攻击一样安全,但是它易于计算,这意味着更容易进行暴力破解或字典攻击。(对于SHA-256之类的后继者也是如此。)根据情况的不同,散列函数的设计成本较高(例如bcrypt),可能是更好的选择。


有些人大声疾呼诸如“ SHA-1损坏”之类的言论,所以我试图理解这到底意味着什么。假设我有一个SHA-1密码哈希数据库,并且攻击者拥有最先进的SHA-1破坏算法,并且拥有100,000台机器的僵尸网络可以访问它。(对10万台家用计算机进行控制将意味着它们每秒可以执行约10 ^ 15次操作。)他们需要多少时间

  1. 找出任何一个用户的密码?
  2. 找出给定用户的密码?
  3. 找出所有用户的密码?
  4. 找到一种以用户身份登录的方法?
  5. 找到一种以特定用户身份登录的方法?

如果密码过大,该如何更改?加盐的方法(前缀,后缀或两者,或诸如xor-ing之类的更复杂的东西)是否重要?

经过谷歌搜索后,这是我目前的理解。如果我误解了一些内容,请纠正答案。

  • 如果没有盐,彩虹攻击将立即找到所有密码(极长的密码除外)。
  • 如果有足够长的随机盐,找出密码的最有效方法是蛮力攻击或字典攻击。碰撞和前映像攻击都无法帮助您找到实际的密码,因此,针对SHA-1的加密攻击没有帮助。甚至使用什么算法都没关系-甚至可以使用MD5或MD4,并且密码也一样安全(因为计算SHA-1散列的速度较慢,所以存在细微差别)。
  • 为了评估“同样安全”的安全性,我们假设一次sha1运行需要1000次操作,并且密码包含大写,小写和数字(即60个字符)。这意味着攻击者每天可以测试10 15 * 60 * 60 * 24/1000〜= 10 17个潜在密码。对于蛮力攻击,这意味着要在3小时内测试所有密码,最多9个字符,一周最多测试10个字符,一年最多测试11个字符。(每个其他字符要花60倍的时间。)字典攻击的速度要快得多(即使攻击者只有一台计算机,也可以在数小时内将其删除),但只能找到弱密码。
  • 要以用户身份登录,攻击者无需找出确切的密码;找到一个导致相同哈希值的字符串就足够了。这称为第一次原像攻击。据我所知,没有针对SHA-1的原像攻击。(A暴力破解攻击需要2点160的操作,这意味着我们的理论,攻击者需要10 30年,把它关闭。的理论可能性的限制是大约2个60操作,在该攻击将需要几年的时间。)有原像攻击反对SHA-1的简化版本(效果可忽略不计)(对于使用44步而不是80步的简化SHA-1,攻击时间从2160次操作减少到2157次)。有一些针对SHA-1的冲突攻击,这在理论上是可行的(我发现的最好的攻击时间从2 80降至2 52),但是对于密码哈希(即使不加盐)也没有用。

简而言之,使用SHA-1存储密码似乎非常安全。我错过了什么?

更新: Marcelo指出了一篇文章,其中提到了2 106次操作的第二次原像攻击。(编辑:正如Thomas所解释的那样,此攻击是一种假想的构造,不适用于现实情况。)不过,我仍然看不到这对使用SHA-1作为关键派生函数的危险。通常有充分的理由认为碰撞攻击或第二原像攻击最终可以转变为第一原像攻击吗?


现在已经7岁了,自从上次编辑以来,发生了很多事情。SHA-1不再被认为足够安全以进行密码散列
GordonM'5

@GordonM发生了什么事?随着计算能力的提高,SHA-1碰撞攻击变得越来越实用,但在这里并没有真正的意义。SHA-1从未真正安全过用于密码哈希(通常不是快速哈希),但就其范围而言,它仍然是AFAIK。
Tgr

SHA-1从来都不是安全的密码哈希,因为它从来没有打算首先保护密码……
Azxdreuwa

Answers:


209

这个问题的简短答案是:SHA-1尽可能安全。MD5也可以,即使是MD4也可以;但这会使一些投资者感到紧张。对于公共关系,即使将其输出截断为160或128位,也最好使用“更好”的哈希函数,例如SHA-256(以节省存储成本)。一些SHA-3第2轮候选者似乎比SHA-1更快,但可以说“更安全”。但是它们仍然有些新,因此现在坚持使用SHA-256或SHA-512将是一条更安全的路线。这会让您看起来专业和谨慎,这很好。

请注意,“尽可能安全”与“完全安全”不同。有关详细说明,请参见下文。

关于已知攻击:

对MD4,MD5和SHA-1的已知攻击是关于冲突的,不会影响原像抵抗。已经表明,MD4有一些弱点,在尝试破坏HMAC / MD4时可以(仅在理论上)加以利用,但这不适用于您的问题。在2 106由Kesley和施奈尔纸第二原像攻击是一个通用的权衡其仅适用于很长的输入(2个60字节;这是一个万TB -通知如何106 + 60超过160;这就是你看到权衡并没有什么魔术)。

此消息的其余部分假定您使用的哈希函数(例如SHA-1)是“黑匣子”,没有攻击者可以使用的特殊属性。即使使用“中断的”哈希函数MD5和SHA-1,这也是您现在拥有的。

关于彩虹表:

“彩虹攻击”实际上是分担字典或蛮力攻击的费用。它是Hellman在1980年首次描述的时间记忆权衡的派生词。假定您有N个可能的密码(这是字典的大小,或者如果您考虑对输出进行以下操作的强行哈希函数,则为2 n) n位),这是一种分时攻击,您可以预先计算N个散列密码并将其存储在一个大表中。如果您对散列输出进行排序,则可以通过一次查找获得密码。一个彩虹表是该表存储与显着降低的空间,一个聪明的办法。您仅存储N / t个散列密码,并使用O(t 2)查找。Rainbow表使您可以虚拟处理比实际存储的要大得多的预计算表。

但是,无论是否彩虹,攻击者仍然必须至少执行一次完整攻击。可以将其视为几个连续的优化层:

  1. 暴力破解/字典攻击的密码破解费用为N。
  2. 使用预先计算的表,攻击者只需支付一次费用N 然后就可以攻击许多密码,而每个密码的额外费用却很少。
  3. 如果预先计算的表是彩虹表,则N可以更大一些,因为可以降低存储成本。N上的瓶颈变成了攻击者可以聚集的CPU能力,而不是其硬盘的大小。

如果N足够大,以至于哈希N个密码的CPU开销是可笑的,那么无论是否使用Rainbow表,这种攻击都是不可行的。这意味着具有80位或更多输出的(耐原像)哈希函数足以使蛮力攻击不可行。

关于盐:

盐是克服预计算的一种方法。在上面的描述中,加盐使攻击者返回到步骤1:加盐可防止攻击者在多个受攻击的密码之间共享O(N)成本。预先计算的表格,即富彩虹的表格,不再可行。

您想加盐是因为当散列数据包含密码(即适合随机人类大脑的某种密码)时N可能会非常低:人类在选择和记住密码方面确实很糟糕。这就是“字典式攻击”的含义:在假设许多用户密码将位于该特殊选择的空间中的前提下,它减少了潜在密码的空间(“字典式”)。

因此,加盐将至少阻止攻击者使用预先计算的表,尤其是预先计算的彩虹表。假设攻击者能够破解一个或两个密码。我们不希望他以很少的额外开销破解其他1000个密码。

另外,加盐对公共关系也有好处。

关于SHA-1的费用:

SHA-1的基本成本是对一个64字节的块进行哈希处理。SHA-1就是这样工作的:先填充数据,然后将其拆分为64字节的块。在Intel Core2系统上,处理单个块的成本约为500个时钟周期,这是针对单个内核的。MD5和MD4更快,分别计数约400和250个周期。不要忘记,大多数现代CPU具有多个内核,因此请相应地相乘。

一些盐腌方案规定了大盐。例如,输入哈希函数的实际上是单个128位盐的40000个连续副本,然后是密码本身。对于合法用户和攻击者而言,这会使密码哈希变得更加昂贵(在我的示例中为10000倍)。这是否一个好主意取决于设置。对于在台式机系统上登录,这很好:用户甚至不会注意到哈希哈希花了10ms的时间,而不是1µs;但是攻击者的成本却增加了十分可观的10000。在每秒拥有数千个客户端的共享服务器上,总成本可能变得过高。从概念上讲,将合法用户和攻击者的门槛提高相同的因素最终并不是好的安全性。但是在某些特定情况下,这可能是一个值得的主意。

关于在线攻击:

以上所有都是关于克服离线攻击的信息。脱机攻击是指攻击者拥有其“测试”密码所需的所有数据的攻击。例如,攻击者可以获得包含哈希密码的数据库副本。在脱机攻​​击中,攻击者仅受其计算资源的限制。相反,在线攻击是指攻击者的每次猜测都必须经过诚实的验证者的攻击(例如,攻击者只是尝试登录受攻击的系统)。通过限制每秒可尝试的密码数量的限制来阻止在线攻击。极端的例子是智能卡,它们在输入三个错误的PIN后就会关闭。

通常,为了获得密码安全性,安排系统不让攻击者进行离线攻击会带来更多收益。Unix系统就是这样做的:哈希密码(以前是世界可读的/etc/password文件)现在在/etc/shadow文件中,除了少数特权应用程序外,该文件还可以防止读取访问。这里的假设是,如果攻击者可以阅读/etc/shadow,那么他可能对系统具有足够的控制权,以至于他不再需要密码了...


5
极好的答案。我唯一不同意的是“从概念上讲,对合法用户提高门槛,攻击者最终就无法获得良好的安全性”-攻击者必须执行用户必须执行的大量操作。为用户登录添加一个时钟周期会为攻击者增加数百万个时钟。
尼克·约翰逊

1
@Thomas这仍然是准确的,并且可能会在不确定的可预见的将来保持准确。由于普通密码的质量较差,黑客可以通过任何形式的哈希猜测出实际的密码。猜中“ 123456”,您将始终获得一些成功。无论您使用哪种密码存储,这都是正确的。
tylerl

1
只是我的观点,但是当更强大的密码加密已经广泛可用时,为什么还要坚持使用SHA1?一年前,MD5被认为是“安全的”,但现在还不是,因为众所周知,SHA1每天都可能发生这种情况。就个人而言,从现在开始,我将押注河豚-在加密社区中它似乎有更好的代表和较少关注的专家,几乎在任何地方都可以使用,因此没有理由与SHA1赌博。
mindplay.dk 2013年

1
我为自己的核心感到震惊,误认为@ThomasPornin给出的答案是MD5对于密码存储是安全的。如果MD5很好,为什么所有人都说不使用它,请使用bcrypt?他们太谨慎了吗?我已经阅读并理解了所有内容,并给人印象是MD5非常糟糕,因为它容易受到暴力攻击。一年前的评论与答案并没有矛盾……
临时用户

1
@Aerovistae:您可能想在security.SE网站上查看该答案;它包含有关密码哈希的更多分析和最新详细信息。
Thomas Pornin '16

30

先前的答案没有提到GPU,GPU可以并行化SHA-1哈希,以至于整个数据库现在可以在几分钟或几小时内被强行强制使用,而不是几天或几周,即使密码已经使用了盐渍。

现代密码哈希算法(例如bcrypt或scrypt)经过专门设计,使其难以在GPU上运行,原因是它们是具有更高内存需求的分组密码(并且GPU中的内存访问无法并行进行)。它们还具有“工作功能”,可以随着技术的进步而使它们变慢。

简而言之,您应该只使用最好的工具来完成工作。SHA-1远远落后于现有技术。

进一步阅读:


2
“诸如bcrypt或PBKDF2之类的现代密码哈希算法是专门为难以在GPU上运行而设计的” -您是说“ bcrypt还是scrypt”?PBKDF2只是迭代哈希,其中没有对GPU造成问题的问题。
Tgr 2012年

4
请让我知道您使用的是哪种GPU,我将购买相同的GPU。如果您可以在“分钟”内执行2 ^ 160 SHA-1计算(这将少于“小时”,因此最多为59分钟),则您每秒必须能够执行10 ^ 44以上的运算。由于PCIe的传输上限约为128GT / s,因此您的GPU也必须具有出色的板载内存。我要它。
戴蒙2012年

3
@Damon:您似乎在假设用户具有“普通”密码(熵的<8位)或“牢不可破”密码(> 60位的熵)。您将完全忽略密码熵在10-60位范围内的所有人。这些用户是bcrypt,rainbow table和GPU的用户,它们通常构成典型用户群的80%。
jammycakes

1
(糟糕...我应该说,“那些是bcrypt,rainbow table和GPU发挥最大作用的用户”)
jammycakes 2012年

3
有关某些统计信息和分析,请参阅troyhunt.com/2011/06/brief-sony-password-analysis.html-虽然36%的用户选择出现在密码词典中的密码,但只有2-3%的用户选择最常用的密码。
jammycakes 2012年

7

您的描述听起来很准确,符合当前的最新水平。

但是,您不应该使用任何哈希函数的单个迭代:至少,您应该迭代多次(哈希的1000次迭代将攻击者的工作增加了1000倍。它使工作量增加了相同的数量,但是您所做的密码散列要比它们少得多。

但是,理想情况下,您应该使用现有的密码存储原语,例如此处所述。


迭代数千次并不是一个您可能想到的好主意。它增加了哈希冲突的风险。yorickpeterse.com/articles/use-bcrypt-fool
jammycakes 2012年

1
那篇文章看起来很混乱。安全的散列函数不会通过迭代散列而损失可观的熵,并且迭代散列是诸如PBKDF2和scrypt之类的密钥扩展方案的核心组件。即使是作者建议的bcrypt,也使用类似的构造。他的“攻击”依赖于找到哈希的原像-在这种情况下,大多数使用该哈希的构造都被彻底破坏了。最后,我不建议人们直接使用迭代哈希,就像我在问题中所说的那样,您应该使用为此目的而设计的现有基元。
尼克·约翰逊

7

SHA1是消息摘要,它从来都不是密码哈希(或密钥派生)功能。(尽管它可以用作KDF的构建块,例如在带有HMAC-SHA1的PBKDF2中。)

密码哈希函数应防御字典攻击和彩虹表。已经设计了几种算法来实现此目标。

当前,最好的选择可能是Argon2。该系列的密码哈希函数在2015年的“密码哈希竞赛”中获胜。

如果Argon2不可用,则唯一的其他标准化密码哈希或密钥派生功能是PBKDF2,这是一个较旧的NIST标准。如果不需要使用标准,则其他选择包括bcryptscrypt

维基百科上有以下功能页面:


4

SHA-1中发现了严重的漏洞,这些漏洞使搜索速度比暴力破解快得多。它在很大程度上仍然很棘手,但是预计情况不会持续太久。偏执的程序员偏爱SHA-2系列产品。

这篇文章中关于2005年最初的结果:

“是时候走路但不能跑到火出口了。您看不到冒烟,但是火警警报响了。”

这并不是说当前的加密分析使SHA-1不安全,而是加密社区担心更坏的消息可能指日可待。这种担心也适用于SHA-2,尽管在更大的搜索空间内,SHA-2仍具有与SHA-1相同的缺陷,因此一直在寻求SHA-3

简而言之,SHA-1目前是安全的,并且可能会持续一段时间,但是加密社区对预后并不满意。


您能提供一个链接吗?就像我说的那样,我能找到的最好的原像攻击使搜索速度提高了8倍,即使如此,您也需要省略SHA-1的一半步骤。(此外,我认为这是第二次原图像攻击,对密码哈希无用。)
Tgr 2010年

鉴于最近的新闻,我也对来自NSA的消息表示怀疑:)
Alex W

4

自2017年2月起,SHA-1将不再被视为安全。Google已经报告了针对完整的,非缩减的SHA-1的碰撞攻击的成功案例(链接到report)。有关Google的公告,请单击此处

编辑:正如其他人指出的那样,密码不容易受到哈希冲突攻击。但是,作为一般准则,对于与安全相关的应用程序,我不会选择SHA-1。有更好的选择。


好的,找到SHA-1碰撞大约花费了6,500 CPU年和100 GPU年,这不是生产攻击。破解密码并不是针对所有可能输入的暴力手段,而是针对10,000,000个常见密码的列表。这是纸
zaph

1
缺陷是仅使用任何哈希函数来保护密码。仅使用哈希函数是不够的,仅添加盐就不足以提高安全性,加密哈希非常快。取而代之的是,使用随机盐在HMAC上迭代大约100毫秒的持续时间,并将盐与哈希一起保存。使用的功能,例如PBKDF2(又名Rfc2898DeriveBytes),password_hash/ password_verifyBcrypt和类似的功能。关键是要使攻击者花费大量时间通过蛮力查找密码。保护您的用户很重要,请使用安全的密码方法。
zaph

冲突不是原图,密码不是签名。冲突攻击对密码无效,因为它们需要了解原始明文。
Tgr

助理:同意,谢谢。Zaph:是的,在我未在此答案中专门解决的推荐做法包括盐腌以防止彩虹攻击和使用慢速加密散列。
亚伦

3

如果存储了加盐密码,则SHA-1可以满足实际用途。SHA-2被认为更安全,但是SHA-1并不是问题,除非您有理由真正地偏执。

这就是NIST 所说的

到目前为止,关于SHA-1的结果并未引起人们对其安全性的质疑。但是,由于技术的进步,NIST计划在2010年前逐步淘汰SHA-1,而采用更大,更强的哈希函数(SHA-224,SHA-256,SHA-384和SHA-512)。


那是NIST在2004 发表的评论。他们的2010年建议草案说SHA-1被批准用于2010
。– Tgr,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.