.NET Core 中最好的密码哈希算法是哪个?

信息安全 密码 哈希 bcrypt 氩2
2021-08-16 15:12:51

在 .NET Core 中选择最佳密码哈希算法时有哪些注意事项?

我读到并非所有散列算法都是合规/未经验证的,所以我对是否从 NuGet 获得各种实现犹豫不决。此外,不建议创建自己的哈希算法,因为验证它需要一些过程/金钱。

目前,我正在使用 .NET Core Identity V3 密码哈希,因为至少它是微软官方提供的。

我读到以下算法是最好的:

  1. 氩气2
  2. bcrypt
  3. 加密
  4. 系列
  5. PBKDF2(.NET Core Identity V3 使用什么)

理想情况下,我想要 Argon2 或 bcrypt。但是,我不想只使用 Google 出现的第一件事。另外,我怎么知道哪些是经过验证/推荐的?

3个回答

Argon2 是最好用的。它已经过充分审查,是深入研究的主题。它被选为密码哈希竞赛 (PHC) 的获胜者,以取代 scrypt,后者具有一些令人讨厌的时间记忆权衡 (TMTO) 攻击,并且在配置上几乎没有那么灵活。


Argon2赢得了 PHC 并基于对权衡攻击的彻底分析。它需要可配置的内存量才能运行,攻击者要么需要每个暴力线程使用那么多内存,要么需要执行更多的计算。每个内存通道都会降低攻击者以内存需求换取时间需求的灵活性。有两种主要的 Argon2 模式,称为 Argon2i 和 Argon2d。前者旨在抵御侧信道攻击,而后者旨在最大限度地提高安全性以抵御离线攻击。还存在一种混合 Argon2id,它使用 Argon2i 进行第一次内存传递,使用 Argon2d 进行后续传递。

bcrypt是根据 Blowfish 的密钥计划设计的较旧的 KDF,速度很慢。它需要 4 KiB 的快速内存来计算,这使得它在基于 GPU 的破解者上效率低下,因为它们使用了竞争内存。这是因为 GPU 有许多核心,但每个核心必须共享对主 VRAM 的访问。因为 bcrypt 在运行时会读取和修改 4 KiB 的状态,所以多个并行 GPU 核心会争夺谁可​​以访问主内存总线,结果是大多数核心处于空闲状态,等待直到他们可以访问他们需要的内存执行 bcrypt 评估。

scrypt是一个内存硬 KDF,但它比 Argon2 受到更严重的 TMTO 攻击。也就是说,如果攻击者没有足够的内存,他们可以在相同的输入上运行 scrypt,而内存少于执行更多操作所需的内存。另外,scrypt 的内部内存和时间要求不是独立的,所以在不增加处理时间的情况下不可能增加内存使用量,反之亦然。对于可能只想在每次计算上花费几十毫秒但又想使用几兆内存的服务器来说,这可能会成为一个问题。

Catena是 PHC 的候选人之一,但它没有赢得比赛。我没有读过这篇论文,所以我真的不能说太多,但是因为它没有获胜,所以它不会有那么多的研究,所以如果有任何问题,可能不会被发现. 然而,这并不是一个糟糕的选择,因为它仍然是重要研究的主题,并且具有坚实的理论基础。我还是不会用。

PBKDF2是最古老的 KDF 之一,并且可能是最常见的。它不是内存困难的,这意味着攻击者可以对其执行大规模并行攻击而不会遇到内存问题。PBKDF2 的工作原理是采用任何键控散列,通常是 HMAC,并多次运行它,这样每个散列评估都依赖于所有先前的散列评估。不幸的是,HMAC 中使用的典型哈希几乎不需要计算内存,因此攻击者可以在 GPU 和 ASIC 上大规模并行蛮力搜索,而不会遇到内存硬 KDF 会导致的问题。

虽然其他回答讨论了列表中每个算法的有效性,但我将尝试从 .NET Core 的角度回答。除非最近发生了变化,否则 .NET Core 中本机支持(即由 Microsoft 编写)的列表中唯一的算法是 PBKDF2。对于某些公司来说,这意味着这是您唯一的选择。如果您有幸使用任何第三方 NuGet 包,那么您会在列表中找到许多其他算法的大量实现,但您必须决定是否信任它们。就个人而言,由于下载量很少,我可能会不习惯使用BCrypt-Official以外的任何东西但即便如此,我可能还想进一步研究它。重要的是要考虑到任何人都可以编写 NuGet 包(如果他们愿意,可以将其称为“官方”),并且大多数包不太可能经过任何审核过程,因此您可以自行完成作业。

尽管 Argon2 是我个人最喜欢的,但它们都是可靠的选择,你可能不会因为选择其中一个而感到奇怪。最重要的是您正确地对系统进行基准测试,以便您选择合理的参数。

使用 Argon2,您还必须选择一种操作模式。有 Argon2i、Argon2d 和 Argon2id。除非你知道你有充分的理由选择前两个中的一个,否则你应该选择 Argon2id。