附录 C:私钥管理与身份恢复(非规范性)
本文档为非规范性内容:讨论私钥管理问题的扩展方案,不是 AUN 核心协议的一部分。
问题背景
当前设计的困境
当前方案:用户自己保存私钥
优点:
- ✅ 安全性高(用户完全控制)
- ✅ 去中心化(无需信任第三方)
- ✅ 符合 PKI 理念
缺点:
- ❌ 用户体验差(需要备份私钥)
- ❌ 私钥丢失 = 身份丢失
- ❌ 跨设备同步困难
- ❌ 普通用户难以理解
现实问题
场景 1:用户换手机
- 私钥在旧手机上
- 新手机无法登录
- 需要手动导出/导入私钥场景 2:用户忘记备份
- 手机丢失/损坏
- 私钥永久丢失
- AID 无法恢复场景 3:多设备使用
- 手机、电脑、平板
- 需要在每个设备上导入私钥
- 或者每个设备一个 AID?PKI 体系的必要性
问题:AUN 是否必须基于 PKI?
PKI 的价值:
- ✅ 去中心化信任(不依赖单一 CA)
- ✅ 证书链验证(可验证到受信 Root CA)
- ✅ 跨域互通(不同 Issuer 互相信任)
- ✅ 抗审查(无法被单点控制)
PKI 的代价:
- ❌ 私钥管理复杂
- ❌ 证书申请流程复杂
- ❌ 证书吊销机制复杂
- ❌ 用户体验差
结论:
- PKI 是必需的:跨域互通和去中心化信任需要 PKI
- 私钥管理可以优化:不是替代 PKI,而是补充
第三方账号绑定的问题
核心问题
如果用户使用 Google 账号登录,私钥在哪里?
选项 A:私钥在 Gateway(不推荐)
用户使用 Google 登录:
1. Gateway 验证 Google OAuth token
2. Gateway 生成私钥
3. 私钥存储在 Gateway 数据库
4. 用户每次登录,Gateway 代理签名问题:
- ❌ Gateway 完全控制私钥
- ❌ 用户无法真正"拥有"AID
- ❌ 这不是去中心化,是传统账号系统
- ❌ Gateway 被攻破 = 所有私钥泄露
选项 B:私钥在客户端,Google 账号用于恢复(有风险)
首次注册:
1. 客户端生成私钥
2. 私钥存储在客户端本地
3. 用户绑定 Google 账号
4. 私钥加密后备份到 Gateway(用 Google ID 派生的密钥加密)
恢复流程:
1. 用户在新设备使用 Google 登录
2. Gateway 验证 Google OAuth token
3. Gateway 返回加密的私钥备份
4. 客户端用 Google ID 派生密钥解密
5. 私钥恢复到新设备问题:
- ❌ 如果 Google 账号被盗,私钥也被盗
- ❌ Gateway 存储加密私钥,仍有风险
- ❌ 加密密钥派生依赖 Google ID(可能变化)
选项 C:私钥在客户端,Google 账号用于授权新设备(需要主设备在线)
首次注册:
1. 主设备生成私钥
2. 私钥存储在主设备
3. 用户绑定 Google 账号(主设备签名授权)
新设备登录:
1. 新设备使用 Google 登录
2. Gateway 验证 Google OAuth token
3. Gateway 通知主设备:"有人用 Google 账号请求授权"
4. 主设备确认后,签发委托证书给新设备
5. 新设备生成自己的私钥,使用委托证书问题:
- ❌ 主设备丢失 = 无法授权新设备
- ❌ 仍然需要主设备在线
Gateway 如何信任第三方账号?
场景:用户使用 Google 账号登录
用户 → Google OAuth → Gateway
Gateway 获得:
- Google User ID: 123456789
- Email: alice@gmail.com
- Name: Alice
问题:
1. Gateway 如何确认这是真实的 Google 响应?
→ 验证 OAuth token 签名
2. Gateway 如何防止伪造的 OAuth 响应?
→ 使用 HTTPS + 验证 Google 的证书
3. 其他 Issuer 的 Gateway 是否信任这个绑定?
→ 不信任!第三方账号只在本 Issuer 内有效信任链问题:
方案 1:Gateway 信任 OAuth Provider
信任链:用户 → Google (OAuth) → Gateway → AID
问题:其他 Issuer 不信任这个绑定
方案 2:跨域信任 OAuth Provider
信任链:用户 → Google (OAuth) → Gateway A → Gateway B
问题:
- 信任链过长
- 如果 Google 账号被盗,AID 也被盗
- 违背 AUN 的去中心化理念结论:
- 第三方账号不能作为跨 Issuer 的身份证明
- 第三方账号只能作为恢复机制的一部分
- 跨 Issuer 通信仍然需要 PKI 证书
推荐方案:分层身份模型
核心思想
区分"身份"和"认证方式"
┌─────────────────────────────────────┐
│ AID (身份层) │
│ - alice.aid.pub │
│ - 由 PKI 证书保证 │
│ - 私钥是身份的根 │
└─────────────────────────────────────┘
↑
│ 绑定
↓
┌─────────────────────────────────────┐
│ 认证方式 (认证层) │
│ - 主设备(私钥在本地) │
│ - 辅助设备(委托认证) │
│ - 第三方账号(恢复机制) │
└─────────────────────────────────────┘主设备(私钥在本地)
用户首次注册:
1. 在主设备(如手机)上生成私钥
2. 私钥存储在设备安全区域(Keychain/Keystore)
3. 申请 AID 证书
4. 主设备是"身份的根"存储位置:
iOS:Keychain(系统级加密,支持 Face ID/Touch ID)
Android:Keystore(硬件支持,TEE/SE)
浏览器:WebCrypto API(不可导出的密钥)
桌面端:操作系统密钥链辅助设备(委托认证)
用户在新设备登录:
1. 新设备生成临时密钥对
2. 主设备扫码授权
3. 主设备用私钥签发"委托证书"
4. 新设备使用委托证书登录
委托证书:
Subject: alice.aid.pub (device-2)
Issuer: alice.aid.pub (主设备签名)
Valid: 30 天(可配置)
Extensions:
- Device ID: device-2
- Device Name: "Alice's Laptop"
- Delegated By: device-1 (主设备)优点:
- ✅ 无需导出主私钥
- ✅ 主设备控制权限
- ✅ 可以随时撤销委托
- ✅ 委托证书有效期短,降低风险
协议方法:
auth.delegate_device
- 主设备签发委托证书
auth.list_devices
- 列出所有授权设备
auth.revoke_device
- 撤销设备授权第三方账号(恢复机制)
用户绑定 Google 账号:
1. 主设备用私钥签名:
"我授权 Google ID 123456789 作为恢复方式"
2. Gateway 存储这个绑定
3. 主设备丢失时,用户可以:
- 使用 Google 登录
- 通过恢复机制重建私钥
- 旧证书自动吊销关键:
- 第三方账号不是"身份",是"恢复方式"
- 需要主设备授权绑定
- 恢复时会生成新的私钥(或重建旧私钥)
信任模型:
其他 Issuer 的 Gateway 信任:
✅ 主设备证书(由 Issuer CA 签发)
✅ 委托证书(由主设备签发,可验证)
❌ 第三方账号(仅用于恢复,不用于跨 Issuer 通信)联系方式绑定与多因素恢复
核心理念
- 协议层面定义绑定和恢复的扩展接口
- 具体实现由应用开发者决定
- 推荐将加密私钥存储到应用开发者的服务器
绑定联系方式
auth.bind_contact # 绑定联系方式(phone/email/其他)
auth.verify_contact # 验证联系方式
auth.list_contacts # 列出已绑定的联系方式
auth.unbind_contact # 解绑联系方式请求示例:
json
{
"jsonrpc": "2.0",
"id": 1,
"method": "auth.bind_contact",
"params": {
"aid": "alice.aid.pub",
"contact_type": "phone",
"contact_value": "+86138****1234",
"verification_code": "123456"
}
}支持的联系方式类型(建议):
phone:手机号(短信验证码)email:邮箱(邮件验证码)oauth:第三方账号(Google/GitHub/微信等)- 自定义类型:由应用开发者扩展
多因素验证恢复
auth.request_recovery # 发起恢复请求
auth.verify_recovery # 提交验证信息
auth.complete_recovery # 完成恢复恢复流程示例:
1. 用户在新设备发起恢复:
auth.request_recovery({
aid: "alice.aid.pub",
recovery_methods: ["phone", "email"]
})
2. 服务端发送验证码到手机和邮箱
3. 用户提交验证码:
auth.verify_recovery({
aid: "alice.aid.pub",
verifications: [
{type: "phone", code: "123456"},
{type: "email", code: "789012"}
]
})
4. 验证通过后,服务端返回加密的私钥备份
5. 客户端解密并恢复身份私钥存储建议
推荐方案:加密私钥存储到应用开发者的服务器
首次创建 AID:
1. 客户端生成私钥对
2. 客户端本地存储私钥(主副本)
3. 使用用户密码派生密钥加密私钥
4. 将加密私钥上传到应用服务器(备份副本)
5. 绑定 phone/email 等联系方式
恢复流程:
1. 用户在新设备通过 phone/email 验证身份
2. 应用服务器返回加密的私钥备份
3. 用户输入密码解密私钥
4. 客户端恢复身份安全考虑:
- 私钥始终加密存储(服务器无法解密)
- 多因素验证防止恶意恢复
- 用户密码不传输到服务器
- 即使服务器被攻破,私钥仍然安全
- 用户忘记密码 = 无法解密备份(需要额外的密码恢复机制)
实施灵活性:
- 协议定义接口,不强制实现细节
- 应用开发者可以选择:
- 存储位置:自己的服务器 / Gateway / 第三方服务
- 加密方式:密码派生 / 生物识别 / 硬件密钥
- 验证方式:短信 / 邮件 / OAuth / 生物识别
- 恢复策略:单因素 / 多因素 / 社交恢复
社交恢复机制(Social Recovery)
核心思路
借鉴以太坊钱包的社交恢复机制:
用户指定 N 个"守护者"(Guardians):
- 守护者 1:用户的另一个设备
- 守护者 2:用户的 Google 账号
- 守护者 3:用户信任的朋友(另一个 AID)
- 守护者 4:Gateway(可选)
- 守护者 5:用户的邮箱
私钥分片存储(门限签名):
- 需要 M/N 个守护者同意才能恢复(如 3/5)初始设置
用户在主设备注册:
1. 主设备生成私钥
2. 私钥分成 5 片(Shamir's Secret Sharing)
3. 分配给守护者:
- 片 1:主设备本地(Keychain)
- 片 2:备用设备(扫码授权)
- 片 3:Gateway(加密存储)
- 片 4:Google Drive(加密文件)
- 片 5:信任的朋友(加密发送)
4. 设置恢复阈值:需要 3/5 片恢复流程
主设备丢失,用户在新设备恢复:
1. 新设备发起恢复请求
2. 联系守护者:
- 备用设备:扫码确认 ✅
- Gateway:验证用户身份(密码/2FA)✅
- Google 账号:OAuth 登录,从 Google Drive 下载 ✅
3. 收集到 3/5 片,重建私钥
4. 私钥恢复到新设备
5. 旧的私钥片自动失效(重新分片)守护者类型
守护者 1:备用设备
验证方式:扫码确认
存储位置:设备本地 Keychain
优点:用户完全控制
缺点:设备丢失则此片丢失守护者 2:Gateway
验证方式:密码 + 2FA
存储位置:Gateway 数据库(加密)
加密方式:用户密码派生的密钥加密
优点:Gateway 无法单独解密
缺点:用户忘记密码则此片无法使用守护者 3:Google 账号
验证方式:OAuth 登录
存储位置:Google Drive(加密文件)
加密方式:用 Google ID 派生的密钥加密
流程:
1. 用户 OAuth 登录 Google
2. 客户端访问 Google Drive API
3. 下载加密的私钥片
4. 用 Google ID 派生的密钥解密
优点:用户熟悉的登录方式
缺点:Google 账号被盗有风险守护者 4:信任的朋友
验证方式:朋友确认
存储位置:朋友的设备
流程:
1. 用户请求恢复
2. 朋友收到通知(通过 AUN 消息)
3. 朋友确认后,发送私钥片
优点:去中心化,无需信任第三方
缺点:需要朋友在线且愿意帮助守护者 5:用户的邮箱
验证方式:邮箱验证码
存储位置:加密邮件
流程:
1. 初始设置时,发送加密邮件到用户邮箱
2. 恢复时,用户提供邮箱验证码
3. 客户端从邮件中提取私钥片
优点:简单,用户熟悉
缺点:邮箱被盗有风险门限签名算法
Shamir's Secret Sharing:
原理:
- 将私钥 S 分成 N 片:S1, S2, ..., SN
- 任意 M 片可以重建 S
- 少于 M 片无法获得任何关于 S 的信息
示例(3/5 阈值):
- 5 个守护者各持有 1 片
- 需要任意 3 片才能重建私钥
- 2 片或更少无法重建
安全性:
- 单个守护者无法访问私钥
- Gateway 被攻破也无法获得私钥
- 用户丢失 2 个守护者仍可恢复实现:
javascript
// 分片
const shares = shamirSplit(privateKey, {
shares: 5, // 总共 5 片
threshold: 3 // 需要 3 片
});
// 重建
const privateKey = shamirCombine([share1, share3, share5]);协议扩展
新增方法:
auth.setup_recovery
- 设置守护者
- 分片私钥
- 参数:
{
guardians: [
{type: "device", device_id: "device-2"},
{type: "gateway", auth: "password+2fa"},
{type: "oauth", provider: "google"},
{type: "friend", aid: "bob.aid.pub"},
{type: "email", email: "alice@example.com"}
],
threshold: 3 // 需要 3/5
}
auth.add_guardian
- 添加守护者
- 重新分片私钥
auth.remove_guardian
- 移除守护者
- 重新分片私钥
auth.list_guardians
- 列出所有守护者
auth.recover_aid
- 发起恢复请求
- 联系守护者
auth.guardian_approve
- 守护者批准恢复
- 提供私钥片简化方案:2/3 恢复
如果社交恢复太复杂,可以用简化方案:
私钥分成 3 片:
- 片 1:主设备(手机)
- 片 2:备用设备(电脑)
- 片 3:Gateway(加密存储)
需要任意 2 片即可恢复场景分析:
| 场景 | 恢复方式 |
|---|---|
| 主设备丢失 | 备用设备 + Gateway |
| 备用设备丢失 | 主设备 + Gateway(重新分片) |
| Gateway 被攻破 | Gateway 只有 1 片,无法单独恢复,用户安全 |
| 主设备和备用设备都丢失 | 无法恢复(建议添加第 4 个守护者) |
密钥恢复后的证书处理
当用户通过多因素验证恢复身份并生成新密钥对后:
原密钥的处理:
- 原私钥不能再签发新的凭证(已丢失或被撤销)
- 原证书对应的公钥仍然存储在证书服务器
- 之前使用原私钥签发的凭证继续有效
新密钥的处理:
- 生成新的密钥对
- 向 CA 申请新证书(使用新公钥)
- 新证书与原 AID 关联
- 可选:将原证书标记为"已恢复"状态
证书服务器的角色:
证书服务器存储:
✅ 历史证书(公钥)
✅ 证书状态(有效/吊销/已恢复)
❌ 私钥(从不存储)
验证流程:
1. 验证者获取证书链
2. 验证证书签名(使用公钥)
3. 检查证书状态(CRL/OCSP)
4. 验证消息签名(使用证书中的公钥)实际场景示例:
场景:Alice 丢失手机,通过 phone + email 恢复身份
恢复前:
- 原私钥:已丢失
- 原证书:cert-v1(公钥 pub-v1)
- 历史消息:使用 pub-v1 验证签名 ✅
恢复后:
- 新私钥:priv-v2
- 新证书:cert-v2(公钥 pub-v2)
- 历史消息:仍使用 pub-v1 验证签名 ✅
- 新消息:使用 priv-v2 签名,pub-v2 验证 ✅私钥存储最佳实践
推荐方案
1. 主私钥:主设备本地(Keychain/Keystore)
- iOS Keychain(支持 Face ID/Touch ID)
- Android Keystore(硬件支持)
- 浏览器 WebCrypto API(不可导出)
2. 备份方案:门限签名(2/3 或 3/5)
- 备用设备
- Gateway(加密)
- 第三方账号(Google Drive 加密)
- 可选:信任的朋友、邮箱
3. 恢复机制:社交恢复或多设备恢复
- 需要 M/N 个守护者同意
- 单个守护者无法单独恢复第三方账号的角色
不是:主要认证方式
不是:私钥存储位置
而是:恢复机制的一部分(守护者之一)关键原则
✅ 私钥永远不以明文形式存储在服务端
✅ 单个守护者无法单独恢复私钥
✅ 用户始终控制私钥(通过多个守护者)
✅ 第三方账号只是恢复方式之一,不是唯一方式
✅ PKI 体系保持不变(跨域互通需要)实施建议
阶段 1:基础实现(MVP)
实现:
✅ 主设备私钥存储(Keychain/Keystore)
✅ 委托设备认证
✅ 简单备份(导出/导入私钥)
不实现:
❌ 门限签名
❌ 社交恢复
❌ 第三方账号绑定阶段 2:增强恢复(推荐)
实现:
✅ 2/3 门限签名
✅ Gateway 加密备份
✅ 备用设备恢复
不实现:
❌ 复杂的社交恢复
❌ 多种守护者类型阶段 3:完整方案(可选)
实现:
✅ 3/5 或更高阈值
✅ 多种守护者类型
✅ 第三方账号绑定
✅ 朋友作为守护者
