SPECIFICATION
第 7 章 安全与加密
7.1 安全模型
DTP 实现 必须 提供端到端加密。安全模型 必须 满足以下不变量:
- 仅目标 iFay 实例 必须 能够解密接收到的 Payload。
- FayGer 运行时环境 不得 在任何情况下访问明文数据。
- 中间网络节点 不得 读取 Payload 明文。
- DTP 实现 不得 自行管理加密密钥。
7.2 加密范围
加密范围 必须 严格限定于 LogicalFrame 的 Payload。
7.2.1 必须加密的内容
以下数据 必须 加密:
- LogicalFrame 的
payload字段(即 Fragment 的data字段以及(若以 Frame 方式承载的)RequestFrame、ResponseFrame、ControlFrame 的内容)。
7.2.2 不得加密的内容
以下数据 不得 加密,必须 以明文传输:
- LogicalFrame 的
header(包括protocolVersion、frameType、fragmentId、agreementId、originTimestamp、dagDependencies、encryptionMetadata、sequenceNumber)。
加密元数据本身 不得 加密,以使接收方能在解密前确定解密参数。
7.3 密钥管理
7.3.1 密钥来源
DTP 实现 必须 使用 CAP 预协商的密钥。具体要求:
- CAP 必须 在连接建立阶段完成身份验证与密钥交换。
- DTP 实现 必须 使用 CAP 提供的
sessionKey进行 Payload 加密/解密。 - DTP 实现 不得 自行生成、协商或交换加密密钥。
7.3.2 CAPContext 接口
DTP 实现 必须 通过以下接口接收 CAP 提供的上下文:
interface CAPContext {
identity: string;
sessionKey: Uint8Array;
verified: boolean;
}
| 字段 | 规范性要求 |
|---|---|
identity | 必须 为对端身份标识 |
sessionKey | 必须 为 CAP 协商出的会话密钥的字节序列 |
verified | 必须 反映 CAP 验证状态 |
7.3.3 CAP 前置条件
DTP 实现 必须 在开始数据传输前验证 CAPContext:
- 如
verified === false,必须 拒绝发送任何数据帧并返回KEY_NOT_READY错误(2002)。 - 如
sessionKey为空或长度无效,必须 返回KEY_NOT_READY错误。 - 协商帧(Request_Frame、Response_Frame)的传输 同样 受此前置条件约束。
7.4 加密元数据
每个 LogicalFrame 的帧头 必须 携带 EncryptionMetadata:
interface EncryptionMetadata {
algorithm: string;
keyVersion: number;
}
7.4.1 算法标识符
algorithm 字段 必须 为加密算法的标识字符串。应 使用以下标准化命名之一:
| 标识符 | 算法 | 状态 |
|---|---|---|
"AES-256-GCM" | AES-256 in Galois/Counter Mode | 推荐 |
"ChaCha20-Poly1305" | ChaCha20 with Poly1305 | 推荐 |
"AES-128-GCM" | AES-128 in Galois/Counter Mode | 可 使用 |
实现 必须 至少支持 AES-256-GCM 与 ChaCha20-Poly1305 中的一种。推荐 同时支持两种以增强互操作性。
实现 不得 使用:
- ECB 模式(不安全)
- 无认证的加密模式(CBC、CTR 不带 MAC)
- 已知存在弱点的算法(DES、3DES、RC4)
7.4.2 密钥版本号
keyVersion 必须 为非负整数,用于支持密钥轮换:
- 当 CAP 触发密钥轮换时,新密钥的
keyVersion必须 严格大于上一个版本。 - 接收方 必须 使用
keyVersion选择对应的解密密钥。 - 实现 应 维护至少一个旧密钥版本以支持飞行中(in-flight)的 Fragment。
7.5 加密往返一致性
实现 必须 满足以下加密往返一致性属性:
- 使用正确密钥(与发送方使用的密钥匹配)加密后再解密,必须 产生与原始 Payload 字节级相同的输出。
- 使用错误密钥解密 必须 失败,必须 返回
DECRYPTION_FAILED错误(2001)。 - 解密失败时,实现 不得 返回部分解密结果或损坏的数据。
7.6 终端侧解密
当终端作为接收方时(数据注入场景):
- DTP_Slave 必须 使用终端在 CAP 连接建立阶段提交的密钥进行解密。
- 该密钥 必须 与终端在 CAP 中提交的私钥/会话密钥对应。
- 终端 不得 接受任何其他密钥的解密结果。
7.7 解密失败处理
实现 必须 按以下规则处理解密失败:
- 单次解密失败:丢弃帧,发送
DECRYPTION_FAILED错误通知(2001)。 - 连续解密失败超过阈值(实现定义,推荐 为 3 次): a. 应 触发 CAP 重新密钥交换。 b. 应 通知上层应用安全异常。
- 实现 不得 在多次解密失败后无限重试同一帧。
7.8 安全威胁防护
实现 必须 通过协议设计防护以下威胁:
| 威胁 | 防护机制 |
|---|---|
| 中间人窃听 | Payload 端到端加密 |
| FayGer 窥探 | Payload 加密,FayGer 仅可见密文 |
| 密钥泄露 | 密钥版本号机制支持密钥轮换 |
| 身份伪造 | 委托给 CAP 验证 |
| 重放攻击 | 序列号单调递增 + 会话绑定 |
| 帧篡改 | 使用认证加密(AEAD)算法 |
7.9 重放保护
实现 必须 通过以下机制防护重放攻击:
- 序列号单调递增:接收方 必须 拒绝序列号小于或等于已确认最高序列号的帧(除非处于续传场景)。
- 会话绑定:序列号空间 必须 与具体会话绑定。新会话 必须 重置序列号。
- AEAD 认证:加密算法 必须 提供消息认证(GCM、Poly1305 等)。
7.10 元数据隐私
实现 应 注意:帧头中的明文元数据 可能 泄露以下信息:
- 通信对端身份(通过
agreementId关联) - 通信时间模式(通过
originTimestamp与sequenceNumber) - 数据传输频率(通过帧之间的时间差)
实现 可 通过以下方式增强元数据隐私:
- 启用流量填充(实现定义)。
- 使用混淆传输层(如基于 TLS 1.3 的 ECH)。
但本规范 不要求 实现提供元数据隐私保护。
