# 附录 C：私钥管理与身份恢复（非规范性）

> **本文档为非规范性内容**：讨论私钥管理问题的扩展方案，不是 AUN 核心协议的一部分。

## C.1 问题背景

### C.1.1 当前设计的困境

**当前方案**：用户自己保存私钥

**优点**：
- ✅ 安全性高（用户完全控制）
- ✅ 去中心化（无需信任第三方）
- ✅ 符合 PKI 理念

**缺点**：
- ❌ 用户体验差（需要备份私钥）
- ❌ 私钥丢失 = 身份丢失
- ❌ 跨设备同步困难
- ❌ 普通用户难以理解

### C.1.2 现实问题

**场景 1：用户换手机**
```
- 私钥在旧手机上
- 新手机无法登录
- 需要手动导出/导入私钥
```

**场景 2：用户忘记备份**
```
- 手机丢失/损坏
- 私钥永久丢失
- AID 无法恢复
```

**场景 3：多设备使用**
```
- 手机、电脑、平板
- 需要在每个设备上导入私钥
- 或者每个设备一个 AID？
```

### C.1.3 PKI 体系的必要性

**问题**：AUN 是否必须基于 PKI？

**PKI 的价值**：
- ✅ 去中心化信任（不依赖单一 CA）
- ✅ 证书链验证（可验证到受信 Root CA）
- ✅ 跨域互通（不同 Issuer 互相信任）
- ✅ 抗审查（无法被单点控制）

**PKI 的代价**：
- ❌ 私钥管理复杂
- ❌ 证书申请流程复杂
- ❌ 证书吊销机制复杂
- ❌ 用户体验差

**结论**：
- **PKI 是必需的**：跨域互通和去中心化信任需要 PKI
- **私钥管理可以优化**：不是替代 PKI，而是补充

## C.2 第三方账号绑定的问题

### C.2.1 核心问题

**如果用户使用 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. 新设备生成自己的私钥，使用委托证书
```

**问题**：
- ❌ 主设备丢失 = 无法授权新设备
- ❌ 仍然需要主设备在线

### C.2.2 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 证书

## C.3 推荐方案：分层身份模型

### C.3.1 核心思想

**区分"身份"和"认证方式"**

```
┌─────────────────────────────────────┐
│         AID (身份层)                 │
│  - alice.aid.pub                    │
│  - 由 PKI 证书保证                   │
│  - 私钥是身份的根                    │
└─────────────────────────────────────┘
              ↑
              │ 绑定
              ↓
┌─────────────────────────────────────┐
│      认证方式 (认证层)               │
│  - 主设备（私钥在本地）              │
│  - 辅助设备（委托认证）              │
│  - 第三方账号（恢复机制）            │
└─────────────────────────────────────┘
```

### C.3.2 主设备（私钥在本地）

```
用户首次注册：
  1. 在主设备（如手机）上生成私钥
  2. 私钥存储在设备安全区域（Keychain/Keystore）
  3. 申请 AID 证书
  4. 主设备是"身份的根"
```

**存储位置**：
```
iOS：Keychain（系统级加密，支持 Face ID/Touch ID）
Android：Keystore（硬件支持，TEE/SE）
浏览器：WebCrypto API（不可导出的密钥）
桌面端：操作系统密钥链
```

### C.3.3 辅助设备（委托认证）

```
用户在新设备登录：
  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
  - 撤销设备授权
```

### C.3.4 第三方账号（恢复机制）

```
用户绑定 Google 账号：
  1. 主设备用私钥签名：
     "我授权 Google ID 123456789 作为恢复方式"
  2. Gateway 存储这个绑定
  3. 主设备丢失时，用户可以：
     - 使用 Google 登录
     - 通过恢复机制重建私钥
     - 旧证书自动吊销
```

**关键**：
- 第三方账号**不是**"身份"，是"恢复方式"
- 需要主设备授权绑定
- 恢复时会生成新的私钥（或重建旧私钥）

**信任模型**：
```
其他 Issuer 的 Gateway 信任：
  ✅ 主设备证书（由 Issuer CA 签发）
  ✅ 委托证书（由主设备签发，可验证）
  ❌ 第三方账号（仅用于恢复，不用于跨 Issuer 通信）
```

## C.4 联系方式绑定与多因素恢复

### C.4.1 核心理念

- 协议层面定义绑定和恢复的扩展接口
- 具体实现由应用开发者决定
- 推荐将加密私钥存储到应用开发者的服务器

### C.4.2 绑定联系方式

```
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/微信等）
- 自定义类型：由应用开发者扩展

### C.4.3 多因素验证恢复

```
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. 客户端解密并恢复身份
```

### C.4.4 私钥存储建议

**推荐方案**：加密私钥存储到应用开发者的服务器

```
首次创建 AID：
  1. 客户端生成私钥对
  2. 客户端本地存储私钥（主副本）
  3. 使用用户密码派生密钥加密私钥
  4. 将加密私钥上传到应用服务器（备份副本）
  5. 绑定 phone/email 等联系方式

恢复流程：
  1. 用户在新设备通过 phone/email 验证身份
  2. 应用服务器返回加密的私钥备份
  3. 用户输入密码解密私钥
  4. 客户端恢复身份
```

**安全考虑**：
- 私钥始终加密存储（服务器无法解密）
- 多因素验证防止恶意恢复
- 用户密码不传输到服务器
- 即使服务器被攻破，私钥仍然安全
- 用户忘记密码 = 无法解密备份（需要额外的密码恢复机制）

**实施灵活性**：
- 协议定义接口，不强制实现细节
- 应用开发者可以选择：
  - 存储位置：自己的服务器 / Gateway / 第三方服务
  - 加密方式：密码派生 / 生物识别 / 硬件密钥
  - 验证方式：短信 / 邮件 / OAuth / 生物识别
  - 恢复策略：单因素 / 多因素 / 社交恢复

## C.5 社交恢复机制（Social Recovery）

### C.5.1 核心思路

**借鉴以太坊钱包的社交恢复机制**：

```
用户指定 N 个"守护者"（Guardians）：
  - 守护者 1：用户的另一个设备
  - 守护者 2：用户的 Google 账号
  - 守护者 3：用户信任的朋友（另一个 AID）
  - 守护者 4：Gateway（可选）
  - 守护者 5：用户的邮箱

私钥分片存储（门限签名）：
  - 需要 M/N 个守护者同意才能恢复（如 3/5）
```

### C.5.2 初始设置

```
用户在主设备注册：
  1. 主设备生成私钥
  2. 私钥分成 5 片（Shamir's Secret Sharing）
  3. 分配给守护者：
     - 片 1：主设备本地（Keychain）
     - 片 2：备用设备（扫码授权）
     - 片 3：Gateway（加密存储）
     - 片 4：Google Drive（加密文件）
     - 片 5：信任的朋友（加密发送）
  4. 设置恢复阈值：需要 3/5 片
```

### C.5.3 恢复流程

```
主设备丢失，用户在新设备恢复：
  1. 新设备发起恢复请求
  2. 联系守护者：
     - 备用设备：扫码确认 ✅
     - Gateway：验证用户身份（密码/2FA）✅
     - Google 账号：OAuth 登录，从 Google Drive 下载 ✅
  3. 收集到 3/5 片，重建私钥
  4. 私钥恢复到新设备
  5. 旧的私钥片自动失效（重新分片）
```

### C.5.4 守护者类型

**守护者 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. 客户端从邮件中提取私钥片
优点：简单，用户熟悉
缺点：邮箱被盗有风险
```

### C.5.5 门限签名算法

**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]);
```

### C.5.6 协议扩展

**新增方法**：

```
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
  - 守护者批准恢复
  - 提供私钥片
```

## C.6 简化方案：2/3 恢复

如果社交恢复太复杂，可以用简化方案：

```
私钥分成 3 片：
  - 片 1：主设备（手机）
  - 片 2：备用设备（电脑）
  - 片 3：Gateway（加密存储）

需要任意 2 片即可恢复
```

**场景分析**：

| 场景 | 恢复方式 |
|------|---------|
| 主设备丢失 | 备用设备 + Gateway |
| 备用设备丢失 | 主设备 + Gateway（重新分片）|
| Gateway 被攻破 | Gateway 只有 1 片，无法单独恢复，用户安全 |
| 主设备和备用设备都丢失 | 无法恢复（建议添加第 4 个守护者）|

## C.7 密钥恢复后的证书处理

当用户通过多因素验证恢复身份并生成新密钥对后：

**原密钥的处理**：
- 原私钥不能再签发新的凭证（已丢失或被撤销）
- 原证书对应的公钥仍然存储在证书服务器
- 之前使用原私钥签发的凭证继续有效

**新密钥的处理**：
- 生成新的密钥对
- 向 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 验证 ✅
```

## C.8 私钥存储最佳实践

### C.8.1 推荐方案

```
1. 主私钥：主设备本地（Keychain/Keystore）
   - iOS Keychain（支持 Face ID/Touch ID）
   - Android Keystore（硬件支持）
   - 浏览器 WebCrypto API（不可导出）

2. 备份方案：门限签名（2/3 或 3/5）
   - 备用设备
   - Gateway（加密）
   - 第三方账号（Google Drive 加密）
   - 可选：信任的朋友、邮箱

3. 恢复机制：社交恢复或多设备恢复
   - 需要 M/N 个守护者同意
   - 单个守护者无法单独恢复
```

### C.8.2 第三方账号的角色

```
不是：主要认证方式
不是：私钥存储位置
而是：恢复机制的一部分（守护者之一）
```

### C.8.3 关键原则

```
✅ 私钥永远不以明文形式存储在服务端
✅ 单个守护者无法单独恢复私钥
✅ 用户始终控制私钥（通过多个守护者）
✅ 第三方账号只是恢复方式之一，不是唯一方式
✅ PKI 体系保持不变（跨域互通需要）
```

## C.9 实施建议

### C.9.1 阶段 1：基础实现（MVP）

```
实现：
  ✅ 主设备私钥存储（Keychain/Keystore）
  ✅ 委托设备认证
  ✅ 简单备份（导出/导入私钥）

不实现：
  ❌ 门限签名
  ❌ 社交恢复
  ❌ 第三方账号绑定
```

### C.9.2 阶段 2：增强恢复（推荐）

```
实现：
  ✅ 2/3 门限签名
  ✅ Gateway 加密备份
  ✅ 备用设备恢复

不实现：
  ❌ 复杂的社交恢复
  ❌ 多种守护者类型
```

### C.9.3 阶段 3：完整方案（可选）

```
实现：
  ✅ 3/5 或更高阈值
  ✅ 多种守护者类型
  ✅ 第三方账号绑定
  ✅ 朋友作为守护者
```

---
