由于 GPU 具有千兆字节的内存,Argon2id 是否也需要使用千兆字节的内存才能有效地阻止 GPU 破解?

信息安全 哈希 记忆 氩2
2021-09-08 22:29:43

对密码哈希算法进行基准测试并选择最慢的可接受成本因子的常见建议不适用于具有多个参数的算法:以内存硬度为代价添加大量迭代会使基准测试时间增加,但如果攻击者仍然可以获取现成的硬件(如普通游戏显卡),那么我不妨使用 pbkdf2 而不是 Argon2id。必须有一些最小的内存量才能使 Argon2id 比 90 年代配置良好的算法更安全,否则我们可以节省开发它的精力。

我会运行基准测试并亲眼看看在 GPU 上散列在什么时候不再比在 CPU 上快,但是 Hashcat 完全缺乏 Argon2 支持。(尽管我选择的任何软件都不一定是最快的实现方式来给我一个正确的答案。)

甚至我 2008 年的旧显卡也有 1GB 的视频内存,而 2020 年的显卡似乎通常有 4-8GB。尽管如此,PHP 中的默认 Argon2id 设置是使用 64MiB 的内存。

如果您将 Argon2id 的并行度设置为您的 CPU 内核数(例如 4 个)并使用此默认内存限制,以下任一(大致)是否正确?

  • 具有 8192MB 内存的 GPU 仍然可以使用 8192/64 = 128 个内核,与 CPU 相比,速度提升了 32 倍。由于内存需求增加,GPU 的减速是线性的。有效阻止 GPU 破解的唯一方法是让 Argon2id 使用比高端 GPU 更多的 RAM,除以您在 Argon2id 中配置的并行度数(即,在此示例中,使用 4 个内核,Argon2id 需要设置为使用8192/4 = 2048MB)。

或者

  • 这个 64MiB 的数量已经使普通消费级 GPU 完全无法破解,因为它太大而无法从简单的 GPU 核心有效使用(因为如果核心必须访问卡的主内存,那么它不值得,或者其他什么) .
2个回答

实用建议

  • 使用 Argon2id。
  • 您使用的内存越多,与您的 CPU 相比,攻击者的优势就越小。
  • 相对于 2021 年 GPU 的绝对数量:
    • 128 MiB 是相当安全的(如果可以的话,不要犹豫,选择 2 GiB 或更多!),
    • 32 MiB 是合理的,并且
    • 4 MiB 明显偏低。
  • 对抗 ASIC,你肯定想走得更高。如果您的对手有 Argon2 ASIC 的预算,那么将几 GB 的常规 RAM 用于密码散列也不是什么奢侈的事情。同样有效的是添加多因素身份验证并强制执行全球唯一密码(检查公共违规行为)。

对于实力较弱的对手,有趣的是,破解软件似乎落后了,截至 2021 年,仍然没有好的 Argon2 破解器可用。Bcrypt 和 scrypt (反过来)比 PBKDF2-class* 算法要好得多,这主要是因为它们的设计更好,但也因为在优化这些强哈希方面投入的精力较少,尤其是在使用 scrypt 的内存大于 16 MiB 时。

* 任何对散列函数进行简单迭代的东西,所以这包括许多开发人员使用的定制设计(d)。Bcrypt 处于更高级别,因为“ Bcrypt 恰好严重依赖于对在整个算法执行过程中不断更改的表的访问。这在 PC 上非常快,在 GPU 上则更不用说了,在 GPU 上共享内存并且所有内核都竞争用于控制内部存储器总线。因此,与攻击者使用 PBKDF2 或类似设计所获得的相比,攻击者从使用 GPU 获得的提升要小得多。 ”——Thomas Pornin 在是否有安全专家推荐 bcrypt 作为密码贮存?

破解内存硬散列

今天发布了一个 hashcat 版本(当我结束我的研究时),它具有更好的 scrypt 支持(另一种内存硬算法)。我一直在使用 RX 5700 GPU 进行测试,按照今天的高价计算,它的价格似乎接近 1000 美元,并且具有 8 GB 的 VRAM。今天早些时候尝试用 hashcat 破解 scrypt 哈希,它已经在 16 MiB 时出错(N=16×1024,r=8,p=1);通过新的更新,我现在可以破解 scrypt 哈希值高达数百兆字节的内存。hashlib.scrypt在 64 MiB 时,hashcat 比使用 OpenSSL 实现的Python 快 17 倍。总比没有好,但相比之下,PBKDF2 在相同的 CPU/GPU 组合上获得了 1000 倍的加速。(而且,据记录,Bcrypt 从 CPU 到 GPU 的速度也提高了 17 倍。)

对于 Argon2,我能找到的最快的破解软件是 CPU 实现。我能找到的唯一看起来不错的GPU 实现在出错之前最多可以分配 434 MiB,但比 PHP 的实现慢(如果我没记错的话,使用 libsodium),不管你使用了多少内存。而且 PHP 也不限制内存使用,它会很高兴地在几秒钟内为您计算 Argon2 和 13 GiB 的 RAM。

理论上

您应该能够分配与 GPU 一样多的内存,即使实际上没有免费的破解软件真正支持它。无论哪种方式,通过要求不断访问主内存而不是能够使用核心本地寄存器,您确实限制了 GPU 的效率:它的内存是全部共享的并且带宽是有限的。CPU 也有同样的限制,但这只是将其置于更公平的竞争环境中。GPU 带宽仍超过 CPU*,但处于同一数量级。

ASIC 是一种下一级攻击,我在写问题时并不担心。但无论如何我现在已经研究过了,GPU 似乎在今天的软件状态下基本上无效,几乎不管你使用什么设置,所以我们不妨考虑一下。

生产 ASIC 的成本似乎主要取决于您需要的内存量。Argon2论文(第 2.1 节)将其描述为:

我们的目标是最大限度地提高 ASIC 密码破解的成本。可以有不同的方法来衡量这个成本,但我们转向最流行的方法之一——时区乘积 [4, 16]。

[...]

  • 50-nm DRAM 实施 [10] 每 GByte 占用 550 mm²;
  • 65-nm 工艺中的 Blake2b 实现大约需要 0.1 mm²(使用 [11] 中的 Blake-512 实现);

它并没有用太多的话来说明,而且论文只谈到了表面积而不是成本,但听起来增加 ASIC 上的 RAM 容量比增加计算能力要昂贵得多。

所以在挑选 Argon2id 参数方面,正确的顺序是:

  1. 首先以时间成本参数 1** 尽可能增加内存使用量。
  2. 在不降低先前参数的情况下尽可能增加并行度,直到达到系统的核心数。
  3. 在不降低先前参数的情况下,尽可能增加时间成本参数。

“尽可能”的意思是:直到它耗尽系统资源(RAM、内核)或者直到它变得比你的用户有耐心的慢。

如果您调整的唯一参数是内存使用情况,这并不奇怪。它可能已经变得很慢了。

并行有点复杂。
在 Argon2 中,设置 p=2 时的两部分可以并行计算,因此如果您的内存参数适合缓存或者如果您使用的可用内存带宽不到一半,则 p=2 在您的 CPU 上花费的时间不应超过 p=1,但应该更强。这似乎在实践中有效:在 PHP(使用 libsodium)中进行测试,增加“线程”设置显然要快得多。(请注意,本文将其称为“通道”以设置“并行”,然后 PHP 将其称为“线程”......)为了确保您充分利用硬件(使 GPU/ASIC 竞争相对困难),建议在增加时间成本参数之前将此设置设置得更高(因为时间成本参数无非是在指定的内存量上多次运行算法)。
加密货币在其论文RFC中并没有多说,但似乎具有相同的功能。在实践中,似乎 scrypt 实现不执行多线程:Hashcat 和 OpenSSL 似乎只需要p倍的时间。还有一个scrypt JavaScript 实现,它“可以在浏览器中进行多线程”,但这似乎只适用于 p=1 和 p=2(同样快)的 Linux 上的 Firefox 或 p=2 和 p 的 Windows 上的 Firefox =4(同样快)。其他值(例如 Windows 上的 Firefox 中的 p=1 和 p=2)线性变慢,其他浏览器(例如ChromiumEdge)似乎根本不支持它。您可能希望寻找支持此功能的实现以获得更强的散列,或者改用 Argon2。

*“在 NVIDIA Tesla K20X 上,CUDA 实现可以达到大约 40-60 GiB/s [...]。相比之下,快速的 Intel Xeon 处理器只能达到大约 10 GiB/s。” --- Panos Kal.,2017 年,关于“在 GPU 上解决比在 CPU 上花费更长的时间来解决的密码算法”

** 由于内存是最重要的,因此时间成本参数最初应设置为 1。这不是不安全的:Argon2 作者Argon2 论文第 6.4 节中写道“同样,T 没有“不安全值” ”,加密论坛研究组写道Argon2id [with] t=1 and 2GiB memory is [ ...] 建议作为所有环境的默认设置。[设置] t=3 和 64 MiB 内存 [...] 建议作为内存受限环境的默认设置。 "

问题的怪癖

问题的措辞表明作者的误解。

提议的陈述“ [X MiB of memory] ​​已经使普通消费者 GPU 完全无效”是完全错误的,因为 GPU 内核可以处理 GPU 拥有的所有内存,但在实际意义上也是正确的,因为当前的实现似乎打破了早在接近 GPU 的实际内存限制之前。给这个值加上一个数字,1 GiB 似乎足以触发这种效果,但解决这个问题是软件问题,而不是硬件限制。

另一种说法“由于内存需求增加而导致 GPU 的减速是线性比例。 ”也是错误的,因为这无法参数化内存带宽差异。并非您可以通过接近破解硬件的内存量来缩小速度差距。另一方面,使用过低的内存参数不会使 CPU 的内存带宽饱和,并为 GPU 破解者提供比较优势,因此(意外地)这里也有一个真理的核心。

作为用户

请记住,您始终可以使用强大且唯一的密码来保护自己的帐户。如果您的密码是 15 个随机字符(从 {az, AZ, 0-9} 中挑选),即使是最愚蠢的密码哈希也是(量子前)安全的。如果您不重复使用密码,那么密码是否被破解也无关紧要。密码管理器可以帮助您生成和管理这些密码。

有不同的方法可以使 Argon2id 的暴力破解更加困难。其中两个如下:

  • 让密码更长,当然也可以让密码随机生成,而不是人为生成
  • 增加工作因子,即使用更多的迭代

只有这样考虑内存因素才有意义,因为将计算能力提高 1-2 个数量级才能真正导致成功的暴力破解。

让我们考虑2个案例。

1. 62字符集20字符密码,8核CPU单核密码哈希耗时1s

需要尝试多少个密码?假设所有可能密码的一半就足够了,我们得到:62^20/2 ~= 10^35。

每年多少个密码可以测试这样的 CPU?8 核 * 60 秒/分钟 * 60 分钟/小时 * 24 小时/天 * 365 天/年 ~= 10^8。

因此需要 10^35 / 10^8 = 10^27 CPU 年。

假设,某些 GPU 比这种 CPU 快 1000 倍。假设某个组织可以买得起 1 000 000 000 个这样的 GPU(世界上只有少数几个国家可以买得起)。然后仍然需要 10^27 / (1 000 * 1 000 000 000) = 10^15 年才能暴力破解这样的密码。

我们将从使用更大的内存因子和降低有效 GPU 功率中获得什么?10^15年的持续时间还不够大吗?在这种情况下,花时间分析哪些内存因素会降低 GPU 的速度是没有意义的。即使是像 10K 这样的小内存因子也足够了,因为 10^15 年的持续时间使得暴力破解变得不可能。

2. 62字符集10字符密码,密码散列在8核CPU单核上耗时0.000001s,或每秒10^6

需要尝试多少个密码?假设所有可能密码的一半就足够了,我们得到:62^10/2 ~= 10^17。

每年多少个密码可以测试这样的 CPU?10^6 * 8 核 * 60 秒/分钟 * 60 分钟/小时 * 24 小时/天 * 365 天/年 ~= 10^14。

因此需要 10^17 / 10^14 = 10^3 = 1000 CPU 年。

如果某个 GPU 比这样的 CPU 快 1000 倍(这太乐观了),那么这样的单个 GPU 可以在 1 年内暴力破解密码。10 个这样的 GPU 可以在 36.5 天内暴力破解密码。许多黑客甚至可以买得起 100 个 GPU。然后密码将在 0,365 天或 9 小时内被暴力破解。

在这种情况下,限制用于暴力破解的核心数量确实可以减慢暴力破解速度,对于一些攻击者来说,这可能是禁止的(太昂贵了),或者暴力破解所需的时间可能会变得更长,因此当密码被暴力破解并且信息被解密,这些信息不再是秘密并且可以免费获得。

TLDR

如果密码熵和工作因数较大,则不需要大内存因数。20 个字符的密码和 1 的哈希生成使得暴力破解成为不可能。由您来计算和决定您可以接受哪些较小的值。

仅当暴力破解的风险很高并且将暴力破解速度降低 1-3 个数量级将暴力破解风险降低到可接受的水平时,大内存因子才有意义。

对你的问题

Argon2id 是否也需要使用千兆字节的内存才能有效地阻止 GPU 破解?

如果您使用相对较长的密码,例如 20 个字符的密码,并且如果 Argon2id 中的工作因子足够大,例如单个密码的散列需要 1 秒,那么不,您不需要为每个密码使用千兆字节的内存,任何小的记忆系数就足够了。

如果您使用相对较短的密码,例如 8-10 个字符长度,并且如果工作因子相对较小,例如单个密码的散列需要 0.000001 秒,那么是的,每个密码使用千兆字节的内存可以减慢暴力破解速度。例如,一些 Nvidia GPU 有大约 6000 个内核和 12 GB RAM。如果您使用例如每个密码 64MB,它将有效地将核心数减少到 192 而不是 ~6000,因此暴力破解将慢 ~ 30 倍。确定要使用多少内存后,检查迭代次数是否太少,请参阅brynk 的注释

为什么要使用 Argon2id?

那为什么要使用 Argon2id,为什么不使用 PBKDF2?因为它具有例如更好的侧通道电阻。在此处查看更多详细信息: