为什么要做 v2?
之前的架构采用双数据密钥:本地 DEK 由 PIN 派生,加密设备数据库;云端 sync DEK 由账号密码派生,加密云端备份。能跑,但有一个结构性问题:用户忘记密码并重置后,新设备或缓存被清的设备就解不开云端 vault。数据等同丢失。
v2 围绕三条原则重建了整个密钥体系:
- 只有一个数据密钥(DEK),永不重加密。任何密码或密钥变更只重新包装 DEK——加密数据本身从不动。
- 服务端永远看不到你的主密码。客户端用 HKDF 派生出一个
loginToken发给服务端;真正解密用的vaultKEK永远不出本机。 - 每一种"忘密码"场景都有明确路径。强制 Recovery Key 保证就算是全新设备没有任何本地缓存,你也能找回数据。
四槽位统一 DEK
v2 的核心是一个 32 字节的 DEK(数据加密密钥),注册时生成一次,账号生命周期内永不更换。你的所有数据——本地数据库、云端同步 blob、附件——都用这一个密钥加密。
然后这个 DEK 被四把独立的密钥分别包装(加密),每把占一个槽位:
- 主密码槽——由 Argon2id 从主密码派生的
vaultKEK包装。主要解锁方式,任何设备都能用。 - PIN 槽(可选)——由 PIN 派生的密钥包装。在常用设备上快速解锁。
- 生物识别槽(可选)——由系统安全区保护、绑定 Face ID/Touch ID/指纹的密钥包装。基于 PIN 槽的便利层。
- 恢复密钥槽(强制)——由注册时仅展示一次的高熵密钥包装。你回到数据的最后保险。
因为四个槽位包装的是同一个 DEK,你可以改主密码、重置 PIN、轮换生物识别,都不需要重新加密任何数据。只有受影响的那个槽位会被重写。
HKDF 如何让服务端无法作弊
你输入主密码时,客户端不会把它发出去,而是执行:
vaultKEK = Argon2id(主密码, salt)——本地用于解包 DEK,永不出本机。loginToken = HKDF(主密码, "login")——一个确定性派生的独立值,仅用于服务端身份验证。
服务端只存 bcrypt(loginToken)。即使整个数据库被拖走,攻击者也得先经过 bcrypt 和 Argon2id 双重爆破主密码,才能碰到你的 vault。vaultKEK 本身从服务端的任何数据中数学上都无法还原。
恢复密钥:你的保险绳
恢复密钥在注册时由你的设备生成,只展示一次。你抄下来、打印或安全保管——我们永远看不到它。它有两个用途:
- 忘记主密码?在任意设备输入恢复密钥,直接解包 DEK,然后立即设置新主密码——数据完好无损。
- 唯一的设备丢了?恢复密钥 + 账号邮箱就足以在新设备上恢复全部数据。
这就是 1Password(Secret Key)和 Bitwarden(Recovery Code)采用的模型。v2 强制启用——不设置恢复密钥就无法开启同步。
多设备透明同步
v1 时代密码重置后在新设备登录可能让你被锁在云端数据外。v2 流程很简单:
- 新设备上用邮箱 + 主密码登录。
- 客户端从服务端下载加密的 vault blob。
- 客户端本地派生
vaultKEK,解包主密码槽,拿到 DEK。 - vault 解密完成。端到端通常在 5 秒内。
不需要缓存密钥。不会再出现"本设备从未同步过,抱歉"的失败。
服务端能做什么、不能做什么
| 能力 | 服务端是否拥有? |
|---|---|
| 看到你的主密码 | ❌ 永远不能 |
看到 vaultKEK 或 DEK | ❌ 永远不能 |
| 看到你的恢复密钥 | ❌ 永远不能(只有 bcrypt(rk_verifier)) |
| 解密你的 vault blob | ❌ 数学上不可能 |
| 验证你的身份 | ✅ 通过 bcrypt(loginToken) |
| 存储加密后的 vault blob | ✅ 仅密文 |
诚实的边界
我们对标 Bitwarden 的安全基线,也诚实地说明这意味着什么:
- v2 是端到端加密,不是 SRP 或 OPAQUE 那样严格的零知识协议。服务端在登录瞬间会在内存中短暂持有
loginToken,落库前才经过 bcrypt。与 Bitwarden 同档。 - 弱主密码是唯一无法靠密码学解决的问题。请使用长 passphrase,并妥善保管恢复密钥。
- 设备被恶意软件入侵(键盘记录、内存抓取)时,没有任何密码管理器能拯救你——这是整个行业的边界。
从 v1 迁移
如果你在 v2 之前就在用 KeyMe Pass,下次解锁应用时会引导你完成一次性迁移:
- 现有数据会用新的统一 DEK 重新包装——这一步数据不离开本地设备。
- 系统会要求你设置恢复密钥,这是重新启用同步的前置条件。
- 你的主密码和 PIN 与之前的体验完全一致,只有底层密钥派生方式变了。
一句话总结
v2 修补了最让我们睡不着的那个结构性缺陷:一次普通的密码重置可能让你丢数据。通过统一 DEK、四个独立解锁槽位、客户端 HKDF 派生和强制恢复密钥,每一种"忘密码"场景现在都有明确、无损的路径——而服务端比以往任何时候知道得都更少。