Argon2id Tuning in Practice: Why 64 MB × 3 Iterations Was the Right Call
How we picked Argon2id parameters for ByteGuard — benchmarks on real iPhones, the OWASP recommendation, the UX vs security trade-off, and what 1Password and Bitwarden chose.
Published: 2026-05-05 · 9 min read
KDF 调参为什么是头等大事
大多数密码管理器把用户的主密码缩短成一个固定长度的加密密钥,靠的是密钥派生函数(KDF)。这个 KDF 是用户被偷走密码库文件之后、攻击者把它变成你明文登录信息之间的最后一道墙。
KDF 弱了,整个加密栈连 AES-256-GCM 一起垮掉。AES 强不强不重要 — 如果 Argon2id 每次只跑 0.1 ms,攻击者租一台 A100 GPU 一小时就能对你的密码库试 100 亿个候选密码。
KDF 强过头了,手机每次按 Face ID 都要等 5 秒才能解锁 App。用户直接卸载。
整个游戏就是:在保证正常解锁延迟的前提下,让攻击者每次猜测付出最大代价。
"每次猜测的代价"是不对称的。你的手机每次解锁只跑一次 KDF — 体感受单次延迟约束。攻击者要跑几十亿次 — 体感受总成本约束。每次猜测代价提高 10 倍,攻击者代价就是用户代价的 10 倍。
为什么选 Argon2id(而不是 PBKDF2 或 scrypt)
Argon2id 是 2015 年 密码哈希竞赛 的冠军,从那以后一直是新系统的推荐 KDF。它有 PBKDF2 没有的三个性质:
- 内存困难性(memory-hard)。Argon2id 每次猜测都要占用 N 兆字节内存。PBKDF2 几乎不占内存,所以攻击者能在单卡 GPU 上同时跑几千个并行猜测。内存困难性把这条路彻底封死 — 每次猜测都得有自己专用的内存块。
- 抗侧信道("id" 模式是混合:第一遍抗侧信道,后续遍抗时间-内存权衡攻击)。
- 参数化工作量。内存成本(m)、迭代次数(t)、并行度(p)都能独立调。PBKDF2 只能调迭代次数。
在攻击规模下,代价差异大约是 1000 倍。一台现代 GPU 矿机每秒能跑约 10⁹ 次 PBKDF2-SHA256,但只能跑约 10⁶ 次 Argon2id (64 MB)。这就是"8 字符密码一夜破解" vs "8 字符密码要花一千夜破解"的差别。
"内存困难"到底是什么意思
具体来说:Argon2id 申请一块 64 MB 内存,用派生字节填满,每个字节都依赖之前所有字节。要算出最终哈希值,算法以一种防止"边算边丢不存"优化的模式遍历这块内存。攻击者没法用空间换时间。
对比 GPU 经济:
- PBKDF2-SHA256:每次猜测约需 32 字节状态。A100 有 40 GB HBM2 → 能跑约 12.5 亿次并行猜测。
- Argon2id (64 MB):每次猜测要 64 MB 状态。同一张 A100 → 只能跑 625 次并行猜测。
同样的硬件,并行槽位少了 200 万倍。这就是内存困难型 KDF 砌起来的结构性护城河。
OWASP 推荐配置(以及我们为什么照搬)
OWASP 密码存储最佳实践 对移动端 / 交互式场景的推荐:
这就是 ByteGuard 用的配置。不是因为我们想保守 — 而是把数据跑了一遍,OWASP 的选择正好落在 iOS 的甜蜜区。
为什么不是 128 MB × 2 iter,或 32 MB × 4?
总工作量大致是 m × t。128×2(256 MB·iter)和 64×3(192 MB·iter)都比 32×4(128 MB·iter)强。光看纸面,128×2 应该是最大代价。但有三个因素把天平拉回 64×3:
- iOS 内存压力。iOS 会激进地杀掉占内存高的后台 App。解锁瞬间临时申请 128 MB 在 iPhone SE / iPhone 12 mini(总 RAM 3-4 GB,可用更少)上会触发 memory warning。64 MB 是个干净的选择。
- UX 延迟。Argon2id 的内存访问比迭代次数更主导挂钟时间。同设备上 128 MB × 2 比 64 MB × 3 慢,尽管工作产出相近。
- 面向未来的方向。内存困难性随攻击者 GPU 内存增长而扩展。GPU RAM 增加时,调高 m,不是 t。从 64 MB 起步,给后续升级到 128 MB / 256 MB 留足头部空间,无需 UX 大手术。
iPhone 真机基准
我们在测试矩阵上的设备测了 Argon2id 64 MB × 3 iter(libsodium crypto_pwhash_str,OPSLIMIT_INTERACTIVE):
| 设备 | 年代 | SoC | 解锁延迟(100 次平均) |
|---|---|---|---|
| iPhone 15 Pro | 2023 | A17 Pro | 180 ms |
| iPhone 14 | 2022 | A15 | 240 ms |
| iPhone 13 mini | 2021 | A15 | 250 ms |
| iPhone 12 | 2020 | A14 | 290 ms |
| iPhone SE (3rd gen) | 2022 | A15 | 250 ms |
| iPhone 11 | 2019 | A13 | 340 ms |
| iPhone XS | 2018 | A12 | 410 ms |
UX 研究文献把"快速反馈"定为 100 ms 以内、"无可感知延迟"定为 200 ms 以内。我们在当前支持设备上停在 180–290 ms — Face ID 之后小但可接受的等待。超过 300 ms 用户开始能感觉到。iPhone XS 落在 410 ms,但 Face ID + Argon2id 一起完成总共还在 700 ms 内,完全在 Apple 自己的 Touch ID / Face ID + Keychain 解锁预算之内。
"100 次平均"很重要,因为冷启动后第一次调用慢 50–100 ms(64 MB 申请的 page-fault)。我们在 App 启动时预热分配器,让用户感知的第一次解锁走的是热路径。
1Password 和 Bitwarden 怎么选的
| 产品 | KDF | 参数 | 备注 |
|---|---|---|---|
| ByteGuard | Argon2id | 64 MB × 3 iter × 1 thread | 按 OWASP 移动端推荐。固定。 |
| 1Password | PBKDF2-SHA256 | 650,000 iterations | 由他们的 128-bit Secret Key 作为第二因子补偿。 |
| Bitwarden | PBKDF2-SHA256 或 Argon2id | PBKDF2: 600,000 / Argon2id: 64 MB × 3 | 2023 起用户可选。Argon2id 是 opt-in,默认还是 PBKDF2。 |
| Apple Keychain | (内部) | (未公开) | Apple Platform Security Guide 没有公开 iCloud Keychain KDF 参数。 |
1Password 的选择是合理的,因为他们的 Secret Key 提供了 128 bit 熵,永远不离开设备。攻击者偷到密码库但拿不到 Secret Key,无论密码强弱都要面对 2¹²⁸ 个候选密钥。ByteGuard 用了同样的架构模式 — 我们的 Secret Key 是 12 词 BIP39 助记词 — 所以 Secret Key 收益加上 Argon2id 内存困难性,叠加优势。
什么时候(以及怎么)我们会重调参数
有两个触发器会强制我们重调:
- 硬件代际推进。当中位支持的 iPhone 比当前新 2 代(即 2027 年基线 = iPhone 13 / A15 起步),我们会考虑把内存提到 96 MB 或 128 MB。Argon2id 的 CPU 成本相对单核性能基本恒定 — 变化的是内存带宽。
- GPU 内存增长。如果消费级 GPU 跳到 128+ GB HBM(目前 A100 是 40 / 80 GB,H100 是 80 GB),64 MB Argon2id 的并行攻击吞吐量会增加。我们会按比例调高 m。
协议本身就内置了版本化:每个 Argon2id 哈希在编码字符串里都带参数($argon2id$v=19$m=65536,t=3,p=1$...)。参数变更后旧密码库在下次解锁时自动重哈希,迁移是增量、静默的。
关键要点
- KDF 强度是其他所有加密保证的基础。随便挑就是 bug。
- Argon2id 在攻击规模下比 PBKDF2 强约 1000 倍,靠的是内存困难性,不是迭代次数。
- OWASP 的 64 MB × 3 iter × 1 thread 是移动端务实的甜蜜区 — 不是最强配置,但是 iPhone 13 / A15 上能在 300 ms 内跑完的最强配置。
- iOS 内存压力是真问题。解锁瞬间申请 128 MB 在低端设备上有 OS 杀掉风险。
- 不要相信"我们用 Argon2id"作为营销话术。问参数:m、t、p。没有这三个数字,这句话毫无意义。
ByteGuard 完整的密钥层级与 iOS Keychain 集成在 安全白皮书 中有详细记录。