ByteGuard Security Architecture: Argon2id, AES-256-GCM, Passkeys, and FIDO2/WebAuthn

A developer walkthrough of ByteGuard Argon2id key derivation, AES-256-GCM field-level encryption, and FIDO2/WebAuthn passkey implementation — with full pipeline diagrams and competitor comparison.

Published: 2026-04-09 · 12 min read

完整加密管线:从 Master Password 到密文

每家密码管理器官网都挂着一页"我们如何加密你的数据"——打开一看,基本都是"军事级加密""银行级防护"这类模糊话术。具体算法?参数?密钥派生层次?一概没有。

这篇文章反过来:每一个参数、每一个设计决策,都能在 ByteGuard 的实际源代码中找到对应。

从你输入 Master Password 的那一刻,到数据变成密文落盘,ByteGuard 走的是一条多阶段管线:密码 + Secret Key → Argon2id → 主密钥 → HKDF → AES-256-GCM,每一步都有明确的安全目标。

ByteGuard 加密管线(完整版)
Master Password
+
Secret Key(128 位)
→
Argon2id(64 MB / 3 次迭代)
→
主密钥(256 位)
→
HKDF-SHA256
→
类型专用密钥
→
AES-256-GCM
→
加密密码库

从用户秘密到密文的完整密钥派生与加密管线

密钥派生的输入是两段秘密的拼接:你的 Master Password,以及设备首次初始化时生成的 128 位 Secret Key。Secret Key 存储在 iOS Keychain,访问策略为 kSecAttrAccessibleWhenUnlockedThisDeviceOnly(不启用 iCloud 同步时)或 kSecAttrAccessibleWhenUnlocked(启用 iCloud 同步时)——设备解锁即可读取,但永远不离开 Keychain 的保护域。单靠任何一个秘密都解不了密:钓鱼拿到了密码?还差 Secret Key。设备被偷了?还差密码。

Argon2id:内存密集型密钥派生

Argon2id——2015 年密码哈希竞赛的获奖算法——是第一个变换步骤。ByteGuard 使用 libsodium 的实现,参数如下:

参数

内存:67,108,864 字节(64 MB)· 迭代次数(opsLimit):3 · 盐值:16 字节 · 输出:32 字节(256 位主密钥)

为什么"吃内存"这么重要?关键在 GPU 的经济账。现代 GPU 有几千个高速 ALU,但单核可用内存极其有限。Argon2id 每轮运算都要随机访问整块 64 MB,必须常驻在快速内存中,没法跨线程共享。

🛡️
Argon2id(ByteGuard)
约 1,000 次并行猜测

每次猜测 64 MB——拥有 64 GB 内存的机器最多只能并行尝试约 1,000 次

⚠️
PBKDF2(传统方案)
数百万次并行猜测

每次猜测内存消耗可忽略——同一台机器可以并行运行数百万次计算

有了 Argon2id,大规模暴力破解在经济上得不偿失——按 1000 次/秒的猜测速率,穷尽一个 256 位密钥空间所需的时间远超宇宙寿命。

定制 ASIC 芯片同样无能为力。ASIC 靠砍掉通用电路来提速,但 Argon2id 每次运算都要大量片上内存,而内存在硅片上非常贵——靠缩小工艺也绕不过去。

HKDF-SHA256:密码学密钥隔离

Argon2id 产出的 256 位主密钥不会直接用于加密数据,而是作为 HKDF-SHA256(基于 HMAC 的密钥派生函数)的输入,派生出一组各有用途的专用密钥:

ByteGuard 采用 KEK/DEK 双层架构。从主密钥派生的只有两把密钥:

🔑
KEK(密钥加密密钥)
info = "KEK-v1"

不直接加密用户数据,而是用来保护下一层的 DEK。

🔒
认证密钥
info = "AUTH-v1"

仅用于身份验证(如解锁时校验),不参与加解密。

真正加密数据的是 DEK(数据加密密钥)——一把随机生成的 256 位密钥,用 KEK 加密后存储。各类型专用的加密密钥再从 DEK 经 HKDF 派生(info=type-login-v1、type-card-v1、type-note-v1、type-identity-v1 等)。

双层结构的好处是:更换 Master Password 时,只需用新 KEK 重新加密 DEK,DEK 本身不变——密码库里成千上万条字段不必重新加密一遍。密钥隔离还带来另一个好处:万一某个漏洞导致某把派生密钥泄露,其他密钥不受影响。

AES-256-GCM:带认证的字段级加密

每个敏感字段使用对应的类型专用密钥通过 AES-256-GCM 独立加密。加密参数如下:

AES-256-GCM

密钥:32 字节(256 位)· 随机数(Nonce):12 字节(96 位),每次加密随机生成 · 模式:Galois/Counter Mode(带认证的加密)

随机 96 位 Nonce 保证同一段明文每次加密出来的密文都不一样,输入和输出之间没有固定对应关系。GCM 的认证标签还能检测篡改——密文哪怕被改了一个比特,解密都会直接失败。

字段级加密意味着每个敏感字段(密码、卡号、备注)都有自己独立的 Nonce 和认证标签,比把整个密码库作为整体加密要精细得多。

▶ 深入了解:Argon2id vs bcrypt vs scrypt

bcrypt 1999 年推出时算是一大进步,但它只固定使用 4 KB 内存。这让 GPU 跑起来毫无压力——现代 GPU 能同时并行几万次 bcrypt 计算,因为每核才 4 KB,几乎不占资源。bcrypt 还有个硬伤:密码输入上限 72 字节,限制了长密码的熵值。

scrypt 2009 年引入了内存密集性,每次哈希要消耗可配置的内存。不过 scrypt 的内存访问是单遍模式,容易被时间-内存权衡(TMTO)攻击钻空子。它也没有混合模式——内存访问要么是数据依赖的(快但容易被侧信道攻击),要么是数据无关的(防侧信道但对 GPU 的抵抗力弱)。

Argon2id 是个混合方案,取两种 Argon2 变体之长。规范上,第一轮的前半部分使用 Argon2i(数据无关寻址,通过缓存/功耗等物理痕迹推测密钥的侧信道攻击对它无效),之后所有轮次切换到 Argon2d(数据依赖寻址,最大化抵抗 GPU 和 ASIC)。这种"两头都占"的设计,正是 Argon2id 拿下密码哈希竞赛冠军并获 OWASP 推荐的原因。

ByteGuard 的参数配置下(64 MB,3 次迭代),在现代 iPhone 上每次哈希大约 0.5–1 秒,用户解锁时几乎无感——但对于要猜几十亿次的攻击者来说,这个速度是致命的。

💡 一句话总结

ByteGuard 的管线分三步,把 Master Password + Secret Key 变成类型专用的加密密钥:Argon2id 让暴力破解在经济上不划算,HKDF-SHA256 在不同数据类型之间做密码学隔离,AES-256-GCM 配合随机 Nonce 实现带认证的字段级加密。

Passkey:让钓鱼在密码学层面不可能

密码有三个天生的硬伤,不管你把复杂度要求定得多高、轮换周期设得多短、安全培训做得多勤,都没法根治:

🎣
钓鱼攻击

一个做得足够逼真的假页面就能骗走凭据。就算是安全从业者,碰上精心伪造的攻击也可能中招。

🔁
撞库攻击

一次数据泄露,足以驱动针对上千个其他网站的自动化撞库。密码重复使用让这类攻击杀伤力倍增。

🔨
暴力破解

"Password123!" 能通过大多数复杂度检查。可预测的套路让字典攻击在大规模场景下效率惊人。

Passkey 基于 FIDO2/WebAuthn 标准,用公钥密码学取代了共享秘密,从根源上消除了这三种威胁。机制很直接——

注册:私钥生成后就再也出不去

Passkey 注册流程
网站发送挑战
→
设备生成 P-256 密钥对
→
私钥条目级加密存入密码库
→
公钥 → 服务器

注册时生成密钥对,公钥交给服务器,私钥留在设备上加密保管

设备会生成一对 ECDSA P-256(ES256,WebAuthn 标准默认算法)密钥。ByteGuard 用 CryptoKit 的 P256.Signing.PrivateKey() 生成密钥对,私钥数据立即通过 AES-256-GCM 条目级加密存入加密密码库——每条 Passkey 用独立派生的密钥加密(info=type-passkey-v1),解密密钥来自前述 DEK 派生链。公钥则以 COSE 格式发给服务器。没有共享秘密,也就没有什么可偷的。

实现细节

私钥以 x963 表示存入密码库;使用时先解密出 P256.Signing.PrivateKey,签名完成后立即从内存中释放。密码库本身又受 Master Password + Secret Key 双秘密保护——想拿到 Passkey 私钥,必须先过完整的加密管线这一关。

认证:每次都是一次全新的挑战

Passkey 认证流程
新挑战
→
生物识别验证
→
用私钥签名
→
验证签名
→
认证成功 ✓

每次认证都用全新挑战,密钥始终不出设备

每次登录,服务器都会发一个全新的挑战。你的设备先通过生物识别(Face ID、Touch ID)解锁密码库、解密出对应 Passkey 私钥,然后用它对挑战签名,把签名发回去。服务器用存着的公钥验证签名。整个过程没有任何秘密在网上传输。

来源绑定:让钓鱼攻击从根上失效

这是 Passkey 最关键的差异。Passkey 在密码学层面绑定了它创建时的精确域名(来源)。你为 bank.com 创建的 Passkey,在 bank-secure.com、bank.com.attacker.net 或其他任何域名上都不会激活。

这是协议层面强制执行的,不需要用户自己去判断。浏览器在放行凭据之前就会做来源校验。即便攻击者在仿冒域名上做出像素级高仿页面也无济于事——Passkey 根本不会响应。

过渡期方案:Passkey、密码、TOTP 三合一

Passkey 的普及在加速,但还远没到全面覆盖的阶段。ByteGuard 就是为这个过渡期设计的:支持 FIDO2/WebAuthn 的网站用 Passkey,不支持的继续用生成的强密码,TOTP/2FA 码也一并管理。三种凭据共用同一套零知识加密管线——都是在密码库里条目级加密、独立派生密钥。

▶ 深入了解:WebAuthn 信赖方 ID 与来源强制执行

在 WebAuthn 规范里,信赖方 ID(RP ID)就是请求认证的网站的有效域名。比如你在 login.example.com 上创建 Passkey,RP ID 一般是 example.com。

认证时,浏览器会在凭据被访问之前先做来源检查:把当前页面的来源跟每条凭据存储的 RP ID 做比对。不匹配?凭据直接不出现,认证静默失败——攻击者连凭据存不存在都不知道。

这个校验发生在浏览器/操作系统层面,不是在 JavaScript 里,恶意页面没法覆盖或绕过。这跟密码自动填充完全不同——密码自动填充可能会被一个长得很像的 URL 骗过去,Passkey 不会。

结果就是:一个托管在假域名上的登录页,做得再像也拿不到任何 Passkey 凭据。钓鱼在协议层面被根本阻断——不是"更难",而是 Passkey 对假域名完全无响应。

💡 一句话总结

Passkey 用公钥密码学替代共享秘密,靠密码学来源绑定从根上杜绝钓鱼攻击。ByteGuard 在同一个加密密码库里同时管理 Passkey、传统密码和 TOTP 码——无论网站是新是旧,全覆盖。

四个刻意的取舍:我们放弃了什么来换安全

每一个架构决策背后都是一次权衡。以下是 ByteGuard 刻意做出的选择,以及每个选择背后的考量。

故意不做:没有"忘记密码"

ByteGuard 没有密码重置、没有恢复邮件、没有安全问题。这是故意的。任何能在没有原始凭据的情况下恢复账户的机制,本质上就是给别人开了一扇能进来的门。

换个角度理解:但凡存在绕过凭据的恢复途径,攻击者就可能找到并利用这条路。

🔓
有密码恢复机制
  • 邮件重置 = 多一条攻击路径
  • 服务器得存恢复数据
  • 给社工攻击留了口子
🔒
零知识设计
  • 没有重置 = 没有备用路径
  • 服务器不存恢复数据
  • 社工攻击无从下手

Secret Key 绑定到设备

128 位 Secret Key 存在设备 Keychain(见前文访问策略),永远不会通过网络传出去。就算你的 Master Password 被钓鱼或偷窥拿到了,攻击者没有你的设备在手,照样推不出加密密钥。

恢复

Secret Key 有一份 BIP39 风格的助记词短语(初始化时一次性展示),本质是 Secret Key 的可读编码,这是唯一的恢复手段。如果 Master Password 和助记词都丢了,你的数据就在密码学层面永久丢失。这是真正零知识架构的代价:没有任何人——不是 ByteGuard,不是 Apple,也不是任何政府——能绕过这层加密。

本地优先 + 可选 iCloud 同步

ByteGuard 默认把密码库存在本地。开启 iCloud 同步后,离开设备的也只有密文。主密钥不碰网络,Secret Key 不出 Keychain。

也就是说 Apple(iCloud 存储提供商)看到的只是一堆加密数据块。就算 iCloud 被泄露了,没有用户的 Master Password 和设备上的 Secret Key,这些密文在计算上不可能被解密。

字段级加密的权衡

逐字段加密而不是把整个密码库打包加密,是一个刻意的架构选择,有得也有失:

✅
优势
  • 按需解密:展示列表时不用碰敏感字段
  • 同步高效:iCloud 只传改了的字段,不用整库上传
  • 暴露面小:解密一个密码不会把所有密码都读进内存
⚠️
代价
  • 加密次数更多:每个字段都要单独跑一轮加解密
  • 存储略增:每个字段都带着自己的 12 字节 Nonce + 16 字节认证标签

在现代硬件(A15 及更新芯片)上,AES-256-GCM 有硬件加速,操作耗时在微秒级;旧机型走软件实现,延迟仍保持在毫秒级。每个字段多出来的存储开销也就几十字节。综合权衡下来,字段级隔离的安全收益远超这点微乎其微的性能与存储代价。

💡 一句话总结

ByteGuard 主动放弃密码恢复的便利来换取零知识保障,把 Secret Key 绑在设备硬件上,同步只传密文,加密做到字段粒度。每个决策都在拉高攻击成本的同时,保持了现代硬件上流畅的使用体验。

横向对比:ByteGuard vs 主流方案

不同密码管理器的安全架构差异不小。下面的对比依据各产品公开的安全文档和白皮书。

对比项 ByteGuard 1Password Bitwarden Apple Keychain
密钥派生 Argon2id(64 MB) Argon2id(参数因客户端而异) PBKDF2 / Argon2id PBKDF2
加密粒度 字段级 条目级 条目级 条目级
第二因素 Secret Key(设备 Keychain) Secret Key(设备 + 紧急套件备份) 无(可选 2FA) Apple ID + 设备
数据存储 本地优先,可选 iCloud 以云端为主 以云端为主 iCloud Keychain
恢复方式 仅助记词短语 紧急套件 邮件/2FA 恢复 Apple ID 恢复
开源 计划中* 否 是(客户端) 否

* 开源审计是 ByteGuard 路线图上的明确目标——在此之前,加密参数可通过应用包内的 libsodium 调用和 CryptoKit 的公开 API 进行验证。

说明

每种方案都有自己扎实的优势。1Password 最早提出 Secret Key 概念,安全口碑一直很好;Bitwarden 客户端开源,谁都能做独立安全审计;Apple Keychain 跟设备深度集成,使用体验最无感。以上对比全部基于公开安全文档——看你自己的威胁模型来选,别只看营销话术。

值得关注的差异:Bitwarden 以前默认用 600,000 次迭代的 PBKDF2,现在在逐步引入 Argon2id(按内存成本折算,Argon2id 64MB/3 ≈ PBKDF2 数千万次迭代)。1Password 用的是 Argon2id,但参数随客户端平台有所不同。Apple Keychain 用的还是 PBKDF2,不过靠硬件密钥存储和设备信任链做了补偿。没有一家方案面面俱到——关键看你更看重开源可审计、生态集成、本地控制,还是针对特定威胁模型的防护。

💡 一句话总结

ByteGuard 的差异化在于字段级加密、本地优先存储,以及 Argon2id + 设备绑定 Secret Key 的组合。竞品各有各的强项——开源透明、云端便捷、生态集成。按你自己的安全需求来选就好。

参数可验证,代码可复现

ByteGuard 在 App Store 免费下载。零知识加密、字段级安全、Passkey 支持、本地优先——专为想真正搞清楚自己数据怎么被保护的开发者和安全从业者打造。每一条加密参数都能在源码里对上号——不信,装来翻一翻。

🎯 现在就做

别停在"军事级加密"的说辞上。花几分钟读完你正在用的密码管理器的白皮书——或者直接来看 ByteGuard 的代码,是骡子是马遛一遛。

在 App Store 下载 ByteGuard →

密码安全系列
← 第一篇:为什么你需要密码管理器 ← 第二篇:加密如何保护你的数据
Download ByteGuard on the App Store