第 8 章:密码学与签名
本章定义 CAP 协议使用的签名算法、密钥格式、密钥生命周期管理和分发要求。本章中的密码学要求是规范性的——任何符合 CAP 协议的实现 MUST 按本章定义实施。
8.1 算法集
CAP v1 定义两套强制实现的签名算法和密钥格式:
| 算法 ID | 算法 | 公钥长度 | 签名长度 | 状态 |
|---|---|---|---|---|
ed25519 | Ed25519(RFC 8032) | 32 字节 | 64 字节 | 必须实现 |
ecdsa-p256-sha256 | ECDSA P-256 + SHA-256(RFC 6979) | 65 字节(未压缩)/ 33 字节(压缩) | 64 字节(DER 编码或 raw) | 必须实现 |
所有 CAP 实现 MUST 同时支持这两套算法。Trusted_Ticket 使用 JWS 时,对应算法名称为:
| CAP 算法 ID | JWS alg 字段 |
|---|---|
ed25519 | EdDSA |
ecdsa-p256-sha256 | ES256 |
8.1.1 算法选择建议
- 优先使用
ed25519:性能更好、签名更短、密钥管理更简单 ecdsa-p256-sha256:在 FIPS 140-3 等监管要求下使用
签发方 SHOULD 在所有新签发的凭证中默认使用 ed25519,除非有明确合规要求。
8.1.2 不允许的算法
CAP v1 实现 MUST NOT 使用以下算法签发或接受新凭证:
- 任何 RSA 签名变体(性能不佳,密钥更大)
- ECDSA secp256k1(非 FIPS 标准曲线)
- ECDSA P-384 / P-521(v1 不强制,未来版本可能加入)
- 任何 SHA-1 派生签名算法
8.2 密钥格式
8.2.1 Ed25519
公钥按 RFC 8032 §5.1.5 编码:
- 32 字节小端序的压缩 Edwards 曲线点
DescriptorPayload 中 signature.signature_value 为 64 字节原始签名(不含 ASN.1 编码)。
JWS 中签名按 RFC 8037 编码,64 字节原始签名 base64url 编码。
8.2.2 ECDSA P-256
公钥按 RFC 5480 编码:
- 未压缩格式:65 字节(0x04 || X || Y)
- 压缩格式:33 字节(0x02/0x03 || X)
实现 MUST 同时接受未压缩和压缩格式公钥。
签名格式:
- DescriptorSignature 中:64 字节原始签名(R || S,每部分 32 字节大端序),不使用 DER
- JWS 中:按 RFC 7518 §3.4 编码(64 字节 R || S)
8.2.3 密钥的二进制表示
VerificationKey.key_material 字段直接存储上述格式的字节序列:
- ed25519 → 32 字节
- ecdsa-p256-sha256(未压缩) → 65 字节
- ecdsa-p256-sha256(压缩) → 33 字节
8.3 签名输入构造
8.3.1 Authorization_Descriptor 签名输入
按以下步骤构造签名输入:
- 取
AuthorizationDescriptor.payload(DescriptorPayload 结构) - 按 RFC 8949 CBOR 确定性编码(Deterministic Encoding)序列化为字节序列
- 该字节序列即为签名算法的输入
CBOR 确定性编码的关键约束(来自 RFC 8949 §4.2):
- map 中的键按字典序排序
- 数值使用最短编码
- 字符串和字节串使用最短长度编码
- 不使用不确定长度编码(indefinite-length encoding)
实现 MUST 严格遵守这些约束以确保跨实现的签名验证一致性。
8.3.2 Trusted_Ticket 签名输入
按 RFC 7515 §5.1 构造 JWS 签名输入:
Signing Input = base64url(UTF8(Header)) + "." + base64url(UTF8(Payload))
其中:
- Header 和 Payload 按 RFC 7159 序列化为 UTF-8 JSON
- JSON 字段顺序:实现 SHOULD 按字典序排序键,但严格的字段顺序要求由 base64url 编码的字节决定
8.3.3 RevocationStatement 签名输入
撤销声明的签名输入构造与 Authorization_Descriptor 相同:
- 移除
signature字段,保留其余 RevocationStatement 字段 - CBOR 确定性编码序列化
- 字节序列作为签名输入
8.4 密钥分发
8.4.1 分发模式
终端 MUST 支持以下两种 Verification_Key 分发模式:
离线预置(Pre-installed)
终端出厂或部署时预置初始 Verification_Key。预置密钥:
- 在
VerificationKey结构中标记source = "pre-installed" - MUST 在制造或部署阶段通过物理或受控的安全通道写入
- 通常对应根级 Descriptor_Issuer(如设备厂商认证 Issuer)
在线分发(RA-distributed)
Registration_Authority 通过在线接口分发新的 Verification_Key:
- 在
VerificationKey结构中标记source = "ra-distributed" - MUST 通过 TLS/mTLS 通道传输(参见 §1.3.4)
- 终端 MUST 验证传输方为已信任的 Registration_Authority
8.4.2 信任锚配置
终端的 Registration_Authority 公钥(用于验证 RA 推送消息的签名)作为信任锚:
- MUST 在终端制造或初次部署时预置
- 仅可通过物理或受控渠道更换
- 不通过 CAP 协议运行时机制更新
8.4.3 分发消息
Registration_Authority 推送的密钥分发消息:
VerificationKeyDistribution {
required version : uint32 (= 1)
required key : VerificationKey
required ra_signature : DescriptorSignature // 由 Registration_Authority 签名
}
终端处理流程:
- 验证
ra_signature是否由信任锚 Registration_Authority 签发 - 验证
key.algorithm在 §8.1 允许的算法集合内 - 验证
key.valid_from与终端当前时间合理(如不超过当前时间 +24 小时) - 写入终端密钥存储
- 向 Registration_Authority 返回确认(确认机制不在本规范范围内)
8.5 密钥存储
终端 MUST 安全存储所有 Verification_Key 和本地签名密钥(参见 §4.4.3)。
8.5.1 存储要求
终端 MUST:
- 加密存储所有密钥的私钥部分(公钥可明文存储)
- 私钥访问受 OS 进程权限保护,仅 Protocol_Engine 可读取
- SHOULD 将私钥保存在硬件安全元件(如 TPM、Secure Enclave、TEE)中
终端 MUST NOT:
- 以明文形式将私钥写入持久化介质
- 将私钥通过 CAP 协议消息传输
- 在调试日志或错误输出中暴露私钥内容
8.5.2 密钥泄露处理
若终端检测到密钥可能泄露(如安全存储被攻击):
- 立即停止使用该密钥
- 通过 §8.6 流程向 Registration_Authority 报告
- 在新密钥分发完成前,相关凭证的校验全部拒绝(保守策略)
8.6 密钥更新与轮换
8.6.1 平滑过渡
Registration_Authority 在轮换 Verification_Key 时 MUST 提供平滑过渡:
- 新密钥分发到所有终端
- 在过渡期内(默认 30 天),新旧密钥并存有效
- 过渡期结束后,旧密钥的
valid_until到期,自动失效
终端在过渡期内 MUST 同时维护新旧密钥,并按 key_id 选择对应密钥进行校验。
8.6.2 紧急撤销
VerificationKeyRevocation {
required version : uint32 (= 1)
required key_id : string
required revocation_time : timestamp
required reason : enum["compromised", "superseded", "ra_decision"]
required ra_signature : DescriptorSignature
}
终端收到撤销消息后 MUST:
- 验证签名来自信任锚 Registration_Authority
- 立即将该 key_id 标记为已撤销
- 后续校验请求中使用该 key_id 的凭证全部拒绝(返回
E_VERIFICATION_KEY_INVALID) - 主动检查所有活跃 Session:使用该 key_id 签发凭证的 Session 强制终止(参见 §5.5)
8.6.3 终端本地签名密钥的轮换
终端为支持 §4.4 转换流程持有的本地签名密钥:
- 每 90 天 SHOULD 自动轮换一次
- 轮换时由终端生成新密钥对,旧密钥继续用于已签发凭证的校验直至全部过期
- 终端 MAY 同时持有最多 4 个本地签名密钥(覆盖最长有效期 + 平滑过渡)
8.7 密码学要求总结
| 要求 | 范围 |
|---|---|
| 签名算法 MUST 在 ed25519 / ecdsa-p256-sha256 中选择 | 所有签名场景 |
| 私钥 MUST 安全存储 | 所有签发方与终端 |
| 公钥分发 MUST 通过加密通道 | Registration_Authority → 终端 |
| 信任锚 MUST 通过物理或受控渠道预置 | 所有终端 |
| CBOR 确定性编码用于离线凭证签名输入 | Authorization_Descriptor、RevocationStatement |
| JWS Compact Serialization 用于在线票据 | Trusted_Ticket |
