2. Cosign 核心概念:签名、验证、PKI 与透明日志
在镜像供应链安全体系中,Cosign 是 Sigstore 项目中最核心的签名工具。它解决了“谁签的、签的什么、是否可信”三个关键问题。本章深入拆解 Cosign 的四大基础支柱:签名(Sign)、验证(Verify)、公钥基础设施(PKI) 与 透明日志(Rekor)。
核心认知:Cosign 并非传统 GPG 签名的简单替代,而是将无密钥(Keyless)签名、短期证书与公开可审计的透明日志深度整合,从根本上降低了密钥管理的安全风险。
2.1 签名(Sign)—— 为镜像绑定数字身份
Cosign 签名是将一个数字签名附加到容器镜像或其摘要(Digest)上的过程。签名本身可以存储在镜像仓库的标签中(.sig 后缀),也可以存储在 OCI 制品仓库中。
2.1.1 签名对象与格式
- 签名对象:通常是对镜像清单(Manifest)的 SHA256 摘要进行签名,而非整个镜像层数据。
- 签名格式:Cosign 默认使用 DSSE(Dead Simple Signing Envelope) 格式,将载荷(Payload)与签名封装在一起,便于传输和验证。
2.1.2 两种签名模式
| 模式 | 密钥来源 | 适用场景 | 安全等级 |
|---|---|---|---|
| 密钥对模式 | 本地生成的私钥/公钥 | CI/CD 流水线、内部私有仓库 | 高(需妥善保管私钥) |
| 无密钥模式(Keyless) | 通过 OIDC 身份(如 GitHub/GitLab CI)从 Fulcio 获取短期证书 | 开源项目、多团队协作、公共仓库 | 极高(无长期密钥泄露风险) |
生产建议:在云原生 CI/CD 环境中,优先使用 Keyless 模式。它利用 OIDC 令牌自动绑定开发者或流水线身份,签名证书有效期通常只有几分钟,极大降低了密钥泄露的爆炸半径。
2.2 验证(Verify)—— 确认身份与完整性
验证是签名的逆过程。Cosign 通过公钥或 Fulcio 证书链,确认签名确实由声称的身份生成,且镜像内容未被篡改。
2.2.1 验证流程三要素
- 提取签名:从镜像仓库拉取
.sig制品。 - 获取公钥/证书:从本地密钥环、Fulcio 根证书或 Rekor 透明日志中获取。
- 校验摘要:计算当前镜像摘要,与签名中封装的摘要进行比对。
2.2.2 验证命令示例
# 使用公钥验证
cosign verify --key cosign.pub myregistry.io/myimage:v1
# 使用 Keyless 模式验证(自动查询 Rekor 和 Fulcio)
cosign verify myregistry.io/myimage:v1
注意:仅验证签名存在是不够的。必须同时验证签名者身份(Subject)是否属于受信任的团队或组织。Cosign 支持通过
--cert-identity 和 --cert-oidc-issuer 参数进行身份约束。
2.3 公钥基础设施(PKI)—— Fulcio 与短期证书链
传统 PKI 依赖长期 CA 证书和复杂的证书吊销列表(CRL)。Cosign 的 PKI 体系——Fulcio——采用了截然不同的设计哲学:短期证书 + 透明日志。
2.3.1 Fulcio 核心设计
- 证书颁发:Fulcio 是一个 OIDC 感知的证书颁发机构。它验证用户的 OIDC 身份(如
user@example.com),然后签发一个 X.509 证书,证书中嵌入了用户的身份信息。 - 证书有效期:默认仅 10 分钟。过期后证书自动失效,无需 CRL。
- 证书链:Fulcio 的根证书公开可查,所有短期证书均可通过根证书验证。
2.3.2 与传统 PKI 对比
| 维度 | 传统 PKI | Fulcio(Sigstore PKI) |
|---|---|---|
| 证书有效期 | 数月到数年 | 数分钟 |
| 吊销机制 | CRL / OCSP(复杂且延迟) | 过期即吊销(无需额外机制) |
| 身份绑定 | 手动审核 | 自动通过 OIDC 令牌绑定 |
| 密钥管理 | 长期私钥,泄露风险高 | 无长期密钥(Keyless) |
2.4 透明日志(Rekor)—— 不可篡改的审计账本
Rekor 是 Sigstore 的透明日志服务,它充当了一个公开的、仅追加的、可验证的签名账本。所有通过 Sigstore 生成的签名元数据都会被记录在 Rekor 中。
2.4.1 Rekor 的核心价值
- 公开审计:任何人都可以查询 Rekor 日志,验证某个镜像在特定时间点是否被签名。
- 防抵赖:签名者无法否认自己曾经签过某个镜像,因为记录永久存在。
- 离线验证:即使 Fulcio 或 Rekor 服务暂时不可用,验证者仍可基于已缓存的 Merkle 树证明进行验证。
2.4.2 Rekor 中的数据结构
| 字段 | 说明 | 示例 |
|---|---|---|
| UUID | 日志条目的唯一标识 | 24296fb24b8ad77a |
| Body | 签名载荷(包含镜像摘要、签名者身份、证书信息) | Base64 编码的 DSSE 信封 |
| IntegratedTime | 条目被写入日志的时间戳 | 1700000000 |
| LogIndex | 条目在日志中的顺序索引 | 12345678 |
| Verification | Merkle 树证明,用于验证条目是否确实在日志中 | 包含根哈希和路径 |
2.4.3 查询 Rekor 日志
# 通过镜像摘要查询签名记录
rekor-cli search --sha256 1a2b3c4d5e6f...
# 通过 UUID 获取具体条目
rekor-cli get --uuid 24296fb24b8ad77a
2.5 四大概念协同工作
签名、验证、PKI 与透明日志并非孤立存在。它们共同构成了 Sigstore 的信任三角:
- Sign 调用 Fulcio 获取证书,生成签名。
- Rekor 记录签名元数据,提供公开审计能力。
- Verify 通过 Fulcio 根证书验证证书链,通过 Rekor 验证签名存在性。
关键结论:Cosign 通过“短期证书 + 透明日志”的组合,将传统 PKI 的“信任但验证”模式升级为“验证且审计”模式。即使攻击者获取了 CI 系统的 OIDC 令牌,也只能在证书有效期内(10分钟)签名,且所有操作都会在 Rekor 中留下永久记录,极大提升了攻击成本和可追溯性。