代码之家  ›  专栏  ›  技术社区  ›  Tgr

sha-1密码存储安全吗?

  •  143
  • Tgr  · 技术社区  · 16 年前

    结论: sha-1对于preimage攻击是安全的,但是它很容易计算,这意味着它更容易发起bruteforce或dictionary攻击。(对于sha-256这样的后继函数也是如此)根据具体情况,设计计算开销较大的散列函数(比如bcrypt)可能是更好的选择。


    有些人经常说“sha-1坏了”之类的话,所以我试图理解这到底是什么意思。假设我有一个sha-1密码散列的数据库,一个拥有最先进sha-1破解算法和拥有100000台机器的僵尸网络的攻击者可以访问它。(控制10万台家用电脑意味着他们可以每秒进行10^15次操作。)他们需要多长时间

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

    如果对密码进行盐渍处理,这会有什么变化?盐析的方法(前缀,后缀,两者,或更复杂的东西,如异或)重要吗?

    这是我目前的理解,经过一些谷歌搜索。如果我误解了什么,请改正答案。

    • 如果没有盐,彩虹攻击会立即找到所有密码(除了非常长的密码)。
    • 如果存在足够长的随机盐,最有效的方法是暴力或字典攻击来找出密码。碰撞和预映像攻击都无助于找出实际密码,因此针对sha-1的加密攻击在这里没有帮助。使用什么算法并不重要——甚至可以使用md5或md4,密码也同样安全(因为计算sha-1散列比较慢,所以略有不同)。
    • 为了评估“同样安全”的安全性,假设一次sha1运行需要1000个操作,密码包含大写、小写和数字(即60个字符)。这意味着攻击者可以测试10 十五 *60*60*24/1000~=10 十七 一天的潜在密码。对于暴力攻击,这意味着在3小时内测试所有密码,最多9个字符,一周最多10个字符,一年最多11个字符。(每增加一个字符就需要60倍)字典攻击要快得多(即使只有一台计算机的攻击者也能在数小时内完成攻击),但只能找到弱密码。
    • 要以用户身份登录,攻击者不需要找出确切的密码;只需找到导致相同哈希值的字符串即可。这称为第一次图像前攻击。据我所知,没有针对sha-1的图像前攻击。(暴力攻击需要2 一百六十 操作,这意味着我们的理论攻击者需要10个 三十 好几年才能成功。理论可能性的极限约为2 六十 攻击需要几年的时间。 preimage attacks against reduced versions of SHA-1 效果可以忽略不计(减少的sha-1使用44步而不是80步,攻击时间从2 一百六十 操作到2 一百五十七 )对sha-1的碰撞攻击在理论上是可行的( the best I found 把时间从2 八十 到2 五十二 ,但是这些对密码散列是没有用的,即使没有盐渍。

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

    更新: 马塞洛指出一篇文章提到 a second preimage attack in 2 106 operations . ( 编辑: AS Thomas explains ,此攻击是一个不适用于实际场景的假设构造。)不过,我仍然不明白使用sha-1作为关键派生函数有何危险。是否有充分的理由认为碰撞攻击或第二次预映像攻击最终会变成第一次预映像攻击?

    7 回复  |  直到 9 年前
        1
  •  204
  •   Jonathan Hall    10 年前

    对你的问题的简短回答是:sha-1是最安全的。MD5也可以,甚至MD4也可以;但这可能会让一些投资者感到紧张。对于 公共关系 ,最好使用“更好的”散列函数,例如sha-256,即使将其输出截断为160或128位(以节省存储成本)。一些 SHA-3 round-2 candidates 看起来比sha-1要快,但可以说“更安全”;但它们还是有点新,所以坚持sha-256或sha-512是目前比较安全的路线。这会让你看起来专业而谨慎,这很好。

    注意“尽可能的安全”并不等同于“完全安全”。请参阅下面的详细解释。

    关于已知攻击:

    已知的对md4、md5和sha-1的攻击是关于碰撞的,碰撞不会影响到预镜像阻力。已经表明,md4有一些弱点,在尝试打破hmac/md4时可以(仅在理论上)利用,但这不适用于您的问题。2 一百零六 Kesley和Schneier在论文中的第二个preimage攻击是一个通用的权衡,它只适用于非常长的输入(2 六十 字节;这是一百万兆字节——请注意106+60是如何超过160的;这就是您看到的权衡没有任何魔力的地方)。

    此消息的其余部分假设您使用的哈希函数(例如sha-1)是一个“黑盒”,没有攻击者可能使用的特殊属性。这就是您现在所拥有的,即使使用了“坏”散列函数md5和sha-1。

    关于彩虹桌:

    “彩虹攻击”实际上是字典或暴力攻击的成本分摊。它是 time-memory trade-off 1980年由赫尔曼首次描述。假设你有 n 可能的密码(这是字典的大小,或2 n 如果您考虑使用 n 有一种分时攻击,在这种攻击中,您可以预先计算 n 散列密码并将其存储在一个大表中。如果对散列输出进行排序,则可以在一次查找中获取密码。一 彩虹桌 是一种很聪明的方法来存储空间大大减少的桌子。你只储存 N/T 散列密码,然后用o破解密码( T 查找。rainbow表允许您虚拟地处理比实际存储的表大得多的预计算表。

    不过,不管彩虹与否,攻击者至少还必须运行一次完整的攻击。这可以看作是几个连续的优化层:

    1. 暴力/字典攻击已经付出了代价 n 破解每个密码。
    2. 使用预先计算的表,攻击者将支付该成本 n 一旦 然后可以攻击 许多的 密码,每个密码的额外成本非常小。
    3. 如果预先计算的表是彩虹表,那么 n 可能会更大,因为 存储 降低了成本。上的瓶颈 n 成为攻击者可以集中的CPU能力,而不是他的硬盘大小。

    如果 n 足够大,以至于哈希运算的CPU开销 n 密码是可笑的,那么这样的攻击是不可行的,无论是否使用彩虹表。这意味着输出为80位或更多的(抗预镜像)哈希函数足以使暴力攻击不可行。

    关于盐:

    盐是一种克服预先计算的方法。在上面的描述中,salt使攻击者返回步骤1:salt防止攻击者共享o( n )在几个被攻击的密码之间花费。预先计算的表格, 前卫 彩虹桌,已经不可行了。

    您需要盐析,因为当哈希数据包含在 密码 ,也就是说,在一个随机的人的大脑中的某种东西,然后 n 可能很低:人类在选择和记住密码方面真的很差。这就是“字典攻击”的意义:在假定许多用户密码将位于特定选定的空间内的情况下,使用一个减少的潜在密码空间(“字典”)。

    因此,salting至少可以防止攻击者使用预先计算的表,特别是预先计算的rainbow表。这假设攻击者 能够破解一两个密码;我们不希望他用很少的额外开销破解1000个其他密码。

    另外,腌制对公共关系也有好处。

    关于SHA-1成本:

    sha-1的基本成本是对64字节块进行哈希运算。sha-1就是这样工作的:数据被填充,然后分成64字节的块。在Intel Core2系统上,处理单个块的成本约为500个时钟周期,这是针对单个核的。MD5和MD4的速度更快,分别为400和250个周期。别忘了,大多数现代CPU都有几个内核,所以要相应地倍增。

    一些盐析方案规定了大量的盐分;例如,进入hash函数的实际上是一个128位盐分的40000个连续副本,后面跟着密码本身。这使得合法用户和攻击者的密码散列更为昂贵(在我的示例中是10000倍)。这是否是个好主意取决于设置。对于在桌面系统上登录来说,这很好:用户甚至不会注意到用了10毫秒来散列他的密码,而不是1秒;但是攻击者的成本增加了非常明显的1万倍。在每秒有数千个客户端的共享服务器上,总成本可能会变得过高。从概念上讲,对于合法用户和攻击者来说,通过相同的因素提高安全性并不是最终的好办法;但是在某些特定情况下,这是一个值得考虑的主意。

    关于在线攻击:

    以上都是关于打败 脱机 攻击。脱机攻击是指攻击者拥有“测试”密码所需的所有数据的攻击;例如,攻击者可以获取包含哈希密码的数据库副本。在脱机攻击中,攻击者仅受其计算资源的限制。相反,一个 在线 攻击是一种攻击,攻击者的每一个猜测都必须经过一个诚实的验证程序(例如,攻击者只是试图登录被攻击的系统)。通过对每秒可以尝试多少个密码实施限制,可以阻止在线攻击。极端的例子是智能卡在三个错误的引脚后关闭。

    通常,对于密码安全性来说,将系统安排为不让攻击者构建脱机攻击会有更大的回报。这就是unix系统所做的:散列密码,它过去在世界上是可读的。 /etc/password 文件,现在在 /etc/shadow 受读访问保护的文件,少数特权应用程序除外。这里的假设是,如果攻击者能够读取 /ETC/影子 ,那么他可能对系统有足够的控制能力,不再需要密码了…

        2
  •  30
  •   Community Mohan Dere    9 年前

    前面的答案并没有提到gpu,它可以与sha-1散列并行,以至于现在整个数据库可以在几分钟或几小时内而不是几天或几周内被强制执行,即使密码已经被修改过。

    现代密码散列算法,如bcrypt或scrypt,由于它们是具有更高内存要求的块密码(并且gpu中的内存访问不能在相同的范围内并行),因此被特别设计为难以在gpu上运行。它们还有一个“工作功能”,随着技术的进步,可以让它们在飞行中变慢。

    简而言之,你应该只使用最好的工具来做这项工作。而沙一号则远远达不到最先进的水平。

    进一步阅读:

        3
  •  7
  •   Nick Johnson    16 年前

    你的描述听起来很符合当前的技术水平。

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

    但是,理想情况下,您应该使用现有的密码存储原语,例如 here .

        4
  •  6
  •   Erwan Legrand    9 年前

    是一个 消息摘要 从未 是密码散列(或密钥派生)函数。(尽管它可以用作kdf的构建块,例如在带有hmac-sha1的pbkdf2中。)

    密码散列函数应该防御字典攻击和彩虹表。为了实现这一目标,设计了几种算法。

    目前,最好的选择可能是 小精灵 . 这一系列密码哈希函数赢得了2015年的密码哈希竞赛。

    如果 小精灵 不可用,唯一的其他标准密码哈希或密钥派生函数是 PBKDF2 ,这是一个古老的NIST标准。如果不需要使用标准,其他选择包括 BCRIPT 以及 解密 .

    Wikipedia有用于这些功能的页面:

        5
  •  4
  •   Marcelo Cantos    16 年前

    在sha-1中发现了严重的漏洞,使得搜索速度远远快于暴力。这在很大程度上仍然是棘手的,但预计这种情况不会持续太久;多疑的程序员喜欢sha-2家族的东西。

    this article 关于2005年的原始结果:

    “是时候走,而不是跑,到消防出口去。你看不到烟,但火警已经响了。”

    并不是当前的密码分析让sha-1不安全,而是密码社区担心更坏的消息可能就在眼前。这种担心也适用于SHA-2,尽管搜索空间要大得多,但它与SHA-1有着相同的缺陷,因此人们一直在寻找 SHA-3 .

    简言之,sha-1目前是安全的,而且可能在未来一段时间内是安全的,但是密码社区对预后感到不安。

        6
  •  4
  •   Aaron    9 年前

    自2017年2月起,SHA-1不再被认为是安全的。谷歌已经报告成功地对完整的、非简化的sha-1轮进行了碰撞攻击( link to report )对于谷歌的声明, click here .

    编辑:正如其他人指出的,密码不易受到散列冲突攻击。不过,作为一般准则,我不会为安全相关应用程序选择sha-1。还有更好的选择。

        7
  •  3
  •   VladV    16 年前

    如果您存储了salted密码,sha-1在实际应用中是可以的。 sha-2被认为更安全,但sha-1不是问题,除非你有理由真正偏执。

    以下是NIST says :

    到目前为止,SHA-1的结果 不要叫保安进入 问题。但是,由于 技术,NIST计划逐步淘汰 SHA-1有利于 更强的散列函数(sha-224, SHA-256、SHA-384和SHA-512) 2010。