4. 验签流程详解:客户端验签步骤、公钥分发、信任根建立

镜像签名验证是供应链安全的核心防线。Cosign 的验签流程并非简单的“签名-验证”二元操作,而是一套包含公钥获取、信任锚定、签名载荷解析、负载校验的完整链路。本章将拆解客户端验签的每一步,并深入探讨公钥分发策略与信任根(Root of Trust)的建立方式。

4.1 客户端验签完整步骤

当客户端执行 cosign verify 命令时,背后依次执行以下 6 个核心步骤:

步骤 操作 说明
1 拉取镜像 Manifest 从容器镜像仓库获取目标镜像的 Manifest 及关联的 .sig 签名镜像 Tag
2 解析签名 Payload 从 OCI 签名层中提取 payload.json(含镜像 Digest 和签名元数据)
3 获取公钥 根据配置从本地文件、KMS、密钥管理服务或 Fulcio 在线 CA 获取公钥
4 签名算法验证 使用公钥对签名进行 ECDSA-P256 / RSA-PSS 算法验证,确认签名与 Payload 匹配
5 负载 Digest 比对 将 Payload 中声明的镜像 Digest 与步骤 1 拉取的 Manifest Digest 进行比对
6 信任链校验 若使用 Sigstore 生态,还需校验证书链是否可追溯到已配置的信任根(Root CA)
关键点:步骤 5 的 Digest 比对是防止“替换攻击”的核心——即使攻击者伪造了签名,只要镜像内容被篡改,Digest 不匹配即可阻断部署。

4.2 公钥分发策略

公钥分发是验签流程中最脆弱的环节。Cosign 支持三种主流分发模式,适用于不同安全等级的场景:

  • 静态公钥文件(Key-Based):将公钥以 .pub 文件形式内嵌到 CI/CD 配置或 Kubernetes Secret 中。适合小团队、离线环境,但存在密钥轮换困难、泄露风险高的缺点。
  • 密钥管理服务(KMS):通过 AWS KMS、GCP Cloud KMS、Azure Key Vault 或 HashiCorp Vault 存储公钥。客户端通过 API 获取,支持审计日志和自动轮换。
  • Sigstore 公钥基础设施(PKI):使用 Fulcio 证书颁发机构签发短期证书,公钥嵌入 X.509 证书中。客户端通过信任根(Rekor + Fulcio Root CA)自动验证,无需手动分发公钥。
策略 分发方式 安全等级 运维复杂度 适用场景
静态公钥文件 本地文件 / Secret 中 低 开发测试、离线环境
KMS 托管 API 调用 高 中 生产环境、合规审计
Sigstore PKI 证书链自动验证 极高 低(客户端自动) 开源项目、多团队协作
避坑提示:静态公钥文件模式下,若公钥被替换,攻击者可签发任意恶意镜像。建议至少使用 KMS 或定期通过 cosign public-key --kms 轮换并校验公钥指纹。

4.3 信任根建立

信任根(Root of Trust)是验签链的起点。Cosign 的信任根建立分为两个层次:

4.3.1 本地信任根(Key-Based 模式)

用户手动将公钥文件放置在客户端可访问路径(如 ~/.cosign/cosign.pub),或通过环境变量 COSIGN_PUBLIC_KEY 注入。客户端在验签时直接加载该公钥作为信任锚点。此模式信任根是静态且单点的。

4.3.2 Sigstore 分布式信任根(PKI 模式)

Sigstore 生态使用 Fulcio Root CA 作为全局信任根。客户端内置 Fulcio 根证书,验签时自动完成以下链式校验:

  1. 从签名镜像中提取签名者证书(由 Fulcio 签发,有效期通常为 10 分钟)。
  2. 验证证书是否由 Fulcio 中间 CA 签发,中间 CA 证书是否由 Fulcio Root CA 签发。
  3. 通过 Rekor 透明日志校验证书是否被记录且未被吊销。
  4. 若所有校验通过,则信任该签名者公钥。

以下 SVG 展示了 Sigstore 模式下客户端验签的完整信任链:

Sigstore 客户端验签信任链 Sigstore 客户端验签信任链 Fulcio Root CA Fulcio 中间 CA 签名者短期证书 镜像签名 Payload Rekor 透明日志 客户端验签流程 1. 提取签名者证书 → 2. 验证证书链至 Fulcio Root CA → 3. 通过 Rekor 校验证书有效性 → 4. 使用证书公钥验签

4.4 验签缓存与冷启动优化

在冷启动场景下,每次 cosign verify 都需要重复执行上述完整流程,尤其是公钥获取和证书链校验会产生显著的网络延迟。常见的优化手段包括:

  • 公钥缓存:将 KMS 或 Fulcio 获取的公钥在客户端内存中缓存 5–15 分钟,避免重复 API 调用。
  • 证书链缓存:缓存 Fulcio 中间 CA 证书和 Rekor 的 Signed Entry Timestamp(SET),减少透明日志查询次数。
  • 签名层本地缓存:将已验签通过的镜像 Digest 与签名元数据写入本地 SQLite 或内存 Map,下次相同 Digest 直接跳过验签。
生产建议:在 Kubernetes 准入控制器(如 Kyverno / OPA)中集成 Cosign 验签时,务必启用 --allow-insecure-registry 仅用于测试环境;生产环境应配合 COSIGN_REPOSITORY 环境变量指定签名存储仓库,并开启 --output text 记录验签日志用于审计。

4.5 信任根建立的最佳实践

实践项 具体操作 收益
使用 Sigstore 作为默认信任根 配置 cosign initialize 下载 Fulcio Root CA 和 Rekor 公钥 消除手动公钥分发,自动信任链验证
定期轮换 KMS 公钥 设置密钥自动轮换策略(如 90 天),并更新客户端信任锚点 降低密钥泄露影响范围
离线环境建立私有信任根 自建 Fulcio 和 Rekor 实例,生成私有 Root CA 并分发到所有客户端 完全控制信任链,不依赖外部网络
验签失败告警 在 CI/CD 中捕获 cosign verify 非零退出码,触发告警并阻断部署 及时感知签名异常或公钥失效

信任根一旦被攻破,整个验签体系将形同虚设。因此,信任根的存储和分发必须独立于镜像仓库,并启用多因素保护(如 HSM 硬件安全模块或 KMS 访问控制策略)。