密钥管理
Anon 使用分层密钥架构,旨在避免以明文将敏感密钥材料持久化到磁盘,并让不同操作只使用所需的最低密钥权限。
密钥层级
Device authenticator (passkey / password)
│
▼
Root secret ← PRF / Argon2id; session memory
│
HKDF derivation
/ \
/ \
Railgun IDB CryptoKey
key (AES-GCM)
PRF 密钥(根密钥)
使用通行密钥进行身份验证时,认证器会提供伪随机函数(PRF),输出与通行密钥凭据关联的确定性秘密值。存储和同步方式取决于认证器。该 PRF 输出是密钥层级的根。它不会写入磁盘,仅在会话期间存在于内存中。
使用密码进行身份验证时,Argon2id 会根据密码和已存储的盐值派生具有相同作用的根秘密值。
HKDF 派生
Anon 使用 HKDF(基于 HMAC 的密钥派生函数)从 PRF 密钥派生两个密钥:
- Railgun 密钥(
anon:railgun:full:v1):同一个密钥用于余额解密(查看)和 zk-SNARK 证明生成(支出)。身份验证时加载,并在会话期间保留于内存中。 - IDB CryptoKey(
anon:secrets:indexeddb:v1):AES-256-GCM 密钥,用于加密和解密 IndexedDB 中的敏感数据,例如助记词和账户数据。身份验证时加载,并在会话期间保留于内存中。
KeyVault(内存缓存)
KeyVault 是存放会话活动密钥的内存单例,其特点是:
- 身份验证成功后填充
- 不写入磁盘
- 注销或关闭窗口时自动清除
- 防止不需要支出密钥的后台页面访问模式接触这些密钥
数据存储位置
| 数据 | 存储位置 | 加密方式 |
|---|---|---|
| 加密的助记词 | IndexedDB | 使用 IDB CryptoKey 的 AES-GCM |
| IDB CryptoKey | Chrome 存储 | 使用 PRF 派生密钥加密 |
| 公开地址 | Chrome 存储 | 明文,地址本身就是公开信息 |
| Railgun 密钥 | 仅内存 | 不持久化 |
| IDB CryptoKey(已解密) | 仅内存 | 不持久化 |
| PRF 密钥 | 仅内存 | 不持久化 |
恢复
如果无法再访问设备,可以使用 12 个单词的助记词恢复钱包。助记词会重新生成所有密钥。请将它离线保存在安全的位置。