如果给定的字符串总是生成相同的散列,散列如何安全?

信息安全 哈希
2021-09-01 18:34:26

我是散列的新手,我知道 MD5(我知道它已经坏了)和 SHA-1 都是固定的散列算法,但是鉴于大多数密码是字典单词或其他类似密码,将其存储在散列中的意义何在如果攻击者可以使用谷歌回溯原始密码?

我的意思是,不是 SHA-1 或 SHA-2 或任何这些算法都变得无用了吗?

4个回答

这就是为什么您需要使用盐的原因。

为每个密码添加一个全局唯一的盐可以确保即使每个密码都相同,它们仍然会生成唯一的哈希值。

也就是说,SHA-1 或 SHA-2 的单次迭代仍然不是散列密码的好方法,因为它们太快了。即使使用独特的盐,现代硬件也能够每秒散列数十亿个候选密码以找到输入。应使用具有适当工作因子的良好慢速算法(例如 bcrypt)来代替

密码散列只是散列的一个非常小的用途。散列本身对于其他用途、将散列与键配对的构造以及其他构造中可能非常有价值。

对于特定的密码散列,一如既往,您应该阅读Thomas Pornin 对如何安全地散列密码的规范答案

对于这个答案,总结是:在密码数据库泄漏的情况下,足够糟糕的密码存储(明文和/或攻击者知道密钥的可逆加密)会使最佳密码变得毫无价值。足够糟糕的密码会使最好的密码存储变得毫无价值。在这个级别上,没有什么是安全的,因为一方或双方未能达到任何一种安全所需的最低标准。

然后我们得到“非常糟糕的密码存储”,比如未加盐的单次哈希迭代。这就像下面的一样,但每次尝试一次适用于每个密码。在这个级别,只有唯一的、疯狂的密码是安全的,因为使用相同密码的两个用户是显而易见的——他们具有相同的哈希值。

然后我们得到“非常糟糕的密码存储”,例如唯一的每行加盐单次哈希迭代。任何散列中,尽管(对攻击者而言)显然较慢,但散列的密码范围较小,在尝试猜测给定时间后毫无价值。

  • 每行唯一盐所做的所有事情都是强制为每个密码散列重新散列每个候选密码
    • 并防止预先计算的哈希值太高。
  • 假设 2015 年 1 月oclHashcat速度为具有 8 个 R9 290X 的单台机器
    • 2.4E17,或每 30 天约 2^57.7 次单次 MD5 尝试
      • 从 Ubuntu 的美国英语小型词典中长度为 7 或以下的所有单词中以密码方式随机选择的或多或少 4 个单词,即大约 21000^4 或 1.9E17 或 2^57.4,就是这个键空间。
      • 是的,“correcthorsebatterystaple”在这个集合中。请参阅我对我是否应该拒绝明显较差的密码以进行进一步计算的回答。
    • 1.2E16,或每 30 天大约 2^53.4 次 SHA-512 尝试
      • 具有大写、小写和数字字符的九个字符加密随机密码与此密钥空间有关(62^9,或 1.35E16,或 2^53.6)。
  • 疯狂的强密码在这里是安全的。
    • 大写、小写和数字的 35 个字符的加密随机密码大致与 192 位加密一样安全,有 62^35、5.4E62 或 2^208.4 的可能性。
  • 强密码可能没问题
    • 由大写、小写、数字和美国键盘符号组成的 20 个字符的加密随机密码大致与 128 位加密一样安全,可能性为 94^20、2.9E39 或 2^131.1。
    • 14 个字符的大写、小写和数字的密码随机密码大约是我在这个级别上所说的“可能几年安全,但几十年不安全”的最小值,62^14,或 1.2E25,或 2^83.4可能性。

在此之后使用良好、可靠的算法,即 PBKDF2、BCrypt 或 SCrypt,迭代次数较少。这是散列对于相当复杂的密码是安全的!

  • 请记住,PBKDF2/RFC2898只是用于多次迭代 HMAC 的构造。
  • 请记住,HMAC/RFC2104只是一个使用哈希(如 SHA-1、或 MD5、或 SHA-512、或 Whirlpool 或 ...)的构造,同时带有密钥和一些数据
  • 假设 2015 年 1 月oclHashcat速度为具有 8 个 R9 290X 的单台机器
    • 2.9E12,或大约 2^41,WPA/WPA2 每 30 天尝试一次
      • 仅由字母和数字(36^8 或 2.8E12)组成的 8 个字符的加密随机密码接近于此。
      • Ubuntu 的美式英语 Small 中长度为 7 或更少的 3 个密码随机选择的单词超过了这个,21000^3,或 9.2E12
      • 一个大写字母、7 个小写字母和一个数字的密码随机模式在这个密钥空间中,26*26^7*10 或 2E12

在此之后使用具有足够多的迭代/工作因子的 PBKDF2、BCrypt 或 SCrypt。在这个级别,散列对于稍微不太复杂的密码和/或稍长的时间是安全的。

请注意,有趣的是,PBKDF2-HMAC-MD5 具有足够高的迭代次数,实际上并没有损坏,尽管您必须是个白痴才能使用它,或者您必须使用类似 FPGA 的东西MD5 有足够的门,但 SHA-1 或 SHA-2 没有。

请注意,攻击者总是获得更多的权力......而且密码泄漏永远存在。所有找到的密码都不应再被认为是安全的——我见过的最大的单词列表包含千兆字节的先前破解或在明文密码中发现的,有些非常复杂……但它们存储得很糟糕,现在在单词列表中。

使用字典的基于规则的攻击是另一个问题的主题:)。

SHA-1 等不是为密码设计的

它们设计用于签署文件(带有已知文本)以防止修改,例如在您的薪水中添加额外的 000。当很难找到具有相同哈希值的随机文档时,要找到一个有意义并达到预期效果的文档将变得更加困难!

加密散列的一个重要属性(与用于数据结构的散列相反)是输入中更改的单个位应生成完全不同的散列,而您无法预测如何撤消此操作。

出于加密密码的目的,这不是必需的(您可以使用很长的盐来隐藏摘要中过于相似的密码;但是拥有这个属性当然很好,所以说 passw0rd 和 password 会产生完全不同的结果)

在密码框之外思考。

如果您添加盐(始终使用盐)并进行足够的迭代以使蛮力代价高昂,则这些哈希可用于密码。但这不是他们的设计目标。设计目标是比特的不可预测的混合,因此每个比特都会改变大约 50% 的输出。

这不是哈希的错,而是用户的错

大多数密码是字典单词或其他类似密码

我的密码是

iL0v3$t4ckExch4n9everymuch<3 xoxoxox

现在使用谷歌在 MD5 或 SHA-1 下查找我的密码的哈希值,我非常怀疑它是在任何彩虹表中预先计算的。事实上,我是一个被黑客入侵的网站的成员,黑客已经在网上发布了我密码的未加盐 MD5 哈希值。直到今天它才可用,我故意在另一个网站上使用相同的密码和电子邮件,看看是否有人会费心创建一个彩虹表来显示我的 26 个字母密码。