为什么现在密码加密依然大多选择 pbkdf2 而不是 argon2

2023-05-09 10:47:07 +08:00
 wenerme

参考 https://npmtrends.com/argon2-vs-pbkdf2

按照如下的分析,应该 argon2 更应该被推广使用

在项目中选择密码哈希算法时,主要考虑以下因素:安全性、性能、可用性和社区支持。以下是关于 Argon2 、bcrypt 、scrypt 和 PBKDF2 的简要比较:

  1. 安全性:

    • Argon2:目前被认为是最安全的密码哈希算法。它赢得了密码哈希竞赛( PHC ),并且具有很好的内存密集度,抵抗侧信道攻击和时间-空间权衡攻击。
    • bcrypt:也是一种安全的密码哈希算法,但相较于 Argon2 ,它的内存密集度较低,抵抗侧信道攻击和时间-空间权衡攻击的能力较弱。
    • scrypt:设计为内存密集型算法,以抵抗大规模定制硬件攻击。它的安全性优于 bcrypt ,但仍然低于 Argon2 。
    • PBKDF2:相对于其他三种算法,PBKDF2 的安全性最低,因为它没有针对 GPU 或 ASIC 攻击的内存密集特性。
  2. 性能:

    • Argon2 、bcrypt 和 scrypt 的性能可以通过调整参数(如内存、迭代次数等)来控制。你可以根据项目的需求和硬件资源调整这些参数。
    • PBKDF2 性能主要取决于迭代次数,但与其他算法相比,它在现代硬件上的性能相对较差。
  3. 可用性:

    • 大多数编程语言和框架都支持这四种哈希算法,但在某些情况下,Argon2 的支持可能不如其他算法广泛。在选择算法时,需要确保所选算法在项目使用的技术栈中可用。
  4. 社区支持:

    • Argon2 、bcrypt 和 scrypt 都拥有相对广泛的社区支持,而且这些算法已经得到了安全研究人员的审查和推荐。PBKDF2 也得到了一定的支持,但相对较弱。

综合考虑上述因素,Argon2 (尤其是 Argon2id 变体)通常是首选算法,因为它在安全性和性能方面表现最佳。如果项目中 Argon2 的支持有限,可以考虑使用 bcrypt 或 scrypt 。PBKDF2 应该作为最后的选择,仅在其他选项不可用时使用。

2862 次点击
所在节点    程序员
16 条回复
liuidetmks
2023-05-09 10:59:25 +08:00
pbkdf2 系统内置,而且是标准。方便

对普通人来说,强度应该够了。
optional
2023-05-09 11:02:49 +08:00
印象中大都用的 bcrypy 吧,pkb 用的多的来源是哪里?
wenerme
2023-05-09 11:05:20 +08:00
wenerme
2023-05-09 11:05:53 +08:00
@liuidetmks 什么系统内置 pbkdf2 ?一般只见内置 bcrypt
Bromine0x23
2023-05-09 11:15:44 +08:00
这不只统计了 npm 么
liuidetmks
2023-05-09 11:25:04 +08:00
@wenerme



iOS/mac commoncrypto -> commonkeyderivation -> CCKeyDerivationPBKDF

https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60049/include/CommonKeyDerivation.h.auto.html


浏览器 webcrypto api 也内置了 pbkdf2 ,https://developer.mozilla.org/zh-CN/docs/Web/API/SubtleCrypto/deriveKey


客户端和浏览器都有现成的实现,多端统一会减少很多工作量吧。
lysS
2023-05-09 14:21:00 +08:00
conn457567
2023-05-09 18:36:41 +08:00
歪一下楼,使用 pdkdf2 加密密码的最佳实践是什么,搜到的介绍里面,这个算法的加密安全性取决于迭代次数,现在我的服务设置的迭代次数是 1W 多次,虽然是安全了,但是每天半夜被人攻击时就回 CPU 告警。现在问题变成攻击者虽然没有破解密码,但是可以直接把我的服务器打死,是我的使用方式不对吗?
xuanbg
2023-05-09 19:17:54 +08:00
密码防爆破的正确姿势是限流啊!!!限制最小间隔为 1 秒,连续错 5 次就锁定 5 分钟。锁定期无论对错一律返回密码错误,这样哪怕你碰到了正确的,也会错过,然后就永远都不可能对了。加密强度高只能防脱裤碰撞,但你这个利人不利己,别的毫无作用。
liuidetmks
2023-05-10 15:42:53 +08:00
@conn457567 这种密钥派生一般是放在用户端操作 ,用户上传上来服务端只需要做比对就行
放在服务端有两个缺点
1. 消耗大量服务端资源
2. 用户原始密码可能被中间人截取

用户端
key = KDF (“密码”)

服务端收到 key ,然后做一个 Hash (这里做 hash 是防止注入攻击,推荐使用 blake ,速度快,安全不输 sha3 ),

如果是注册,就存库,
如果是登录,就和存库的做比较


这样,用户的口令就没其他人知道了。你只能重置,而不能获取到原文
conn4575
2023-05-10 19:11:40 +08:00
@liuidetmks 懂了,我现在是客户端走的 https 明文传给服务端,服务端加密。
CLMan
52 天前
你这错得有点离谱,密码存储引入 hash 的历史原因有两个:

- 避免数据泄露,导致攻击者获得本应用的所有账户和明文密码
- 避免被拿去撞库

第一个是重中之重,影响了公司的生死存亡。第二个只能说是附带的,毕竟自己活着才最重要。

因为第一个原因,所以密码存储才经历了通用哈希算法、通用哈希算法+盐、标准密码哈希算法的技术演进。

而客户端 hash ,仅有的作用就是避免第二个原因,尚且属于程序员群体的争论点,并非最佳实践,大部分互联网公司都没有这么做。

现在你为了一点性能,将标准密码哈希算法丢到客户端,而服务端居然使用上古的通用哈希算法解决方案,连盐都舍不得加,不是捡了芝麻丢了西瓜。

事实上,你只要阅读一下你所推崇的 blake2 的官网,就会看到它根本不推荐将 blake2 用作密码存储:“Q: So I shouldn't use BLAKE2 for hashing user passwords?”,而是建议使用标准密码哈希算法。
CLMan
52 天前
@liuidetmks 补充 @,内容见上一楼。
liuidetmks
48 天前
@CLMan 关于 blake 部分那部分,你可能误会了,你仔细看看就知道,主要依赖的是 KDF(密钥派生函数),将低熵输入派生出高强密码,浏览器原生支持 pbkdf2

在客户端运行 kdf 没有任何问题,实际上火狐的账号系统就是这么干的,而且我认为应该这么做,凭什么用户口令需要通过你服务器,口令明文最好不要离开用户自己的设备

https://hacks.mozilla.org/2018/11/firefox-sync-privacy/


https://hacks.mozilla.org/wp-content/uploads/2018/11/Sync-Blogpost1.png

服务端对用户上传的高强度进行的 hash 比较,仅仅是为了防止注入,这里也可以像普通公司常用实践一样,加上 salt 再比较

这里当然像火狐一样,使用慢 hash 最好,不过你肯定不想老板问,为什么双 11 我们加了这么多资源,还是卡

随着在 sha3 中竞争中失败,对 blake 家族命运不太看好了
CLMan
48 天前
blake 部分原文指的应该是对用户明文进行 hash ,而你所指的是对派生密码进行 hash ,所以强度来讲确实没什么问题。

火狐的办法确实巧妙,因为它是拿用户明文生成的加密密钥,自然是不能上传明文密码,所以最好在客户端使用 KDF 。
wenerme
40 天前
> 在客户端使用 KDF

那不等同于数据库存储的是 plain 的密码了么?如果数据泄漏,那么客户端直接 post 到获取到的 hash 就能匹配对 password 了。如果想增加客户端的 PoW ,那不如引入专门的 captcha 来做。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/938519

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX