3、镜像签名技术原理:数字签名基础(非对称加密、哈希)、Cosign与Notation对比、签名格式与存储位置

容器镜像签名是云原生供应链安全的核心防线。本章从数字签名的底层原理出发,深入剖析非对称加密与哈希算法的协作机制,并对比当前两大主流签名工具——Cosign 与 Notation 的设计哲学、签名格式与存储策略,帮助你在工程选型中做出合理决策。

3.1 数字签名基础:非对称加密与哈希

数字签名的本质是“用私钥加密摘要,用公钥验证签名”。整个过程依赖两个核心密码学原语:哈希函数(Hash Function)与非对称加密(Asymmetric Cryptography)。

3.1.1 哈希函数:数据指纹

哈希函数将任意长度的数据映射为固定长度的摘要(Digest),具有以下特性:

  • 单向性:无法从摘要反推出原始数据。
  • 抗碰撞性:极难找到两个不同数据产生相同摘要。
  • 敏感性:原始数据微小变化会导致摘要完全改变。

在镜像签名中,哈希函数用于对镜像 Manifest 或 Layer 计算摘要,确保签名对象不可篡改。常用算法包括 SHA-256(默认)和 SHA-384。

3.1.2 非对称加密:密钥对与签名验证

非对称加密使用一对密钥:私钥(Private Key)和公钥(Public Key)。私钥由签名者秘密保管,公钥可公开分发。签名流程如下:

  1. 签名者使用私钥对镜像摘要进行加密,生成签名。
  2. 验证者使用签名者的公钥解密签名,得到摘要 A。
  3. 验证者对镜像重新计算摘要 B,比较 A 与 B 是否一致。

若一致,则证明镜像未被篡改且确实由私钥持有者签名。

工程提示:私钥是签名体系中最敏感的资源。生产环境中应使用硬件安全模块(HSM)或密钥管理服务(KMS)存储私钥,避免私钥泄露导致信任体系崩塌。

3.1.3 数字签名流程示意图

下图展示了从镜像摘要计算到签名生成与验证的完整流程:

数字签名流程示意图 数字签名流程:签名与验证 镜像 Manifest SHA-256 摘要 私钥加密 → 签名 签名 + 镜像 镜像 Manifest SHA-256 摘要 B 公钥解密 → 摘要 A 比较 A == B ? 验证通过/失败 签名者使用私钥加密摘要;验证者使用公钥解密并比对摘要,确保镜像完整性与身份真实性

3.2 Cosign 与 Notation 对比

Cosign 和 Notation 是当前容器镜像签名领域的两大主流工具。两者在签名格式、密钥管理、生态集成等方面存在显著差异。下表从多个维度进行对比:

对比维度 Cosign Notation
发起组织 Sigstore 社区(Linux 基金会) CNCF(云原生计算基金会)
签名格式 基于 OCI 制品规范,签名存储为独立 OCI 制品 基于 OCI 制品规范,遵循 Notary 项目签名规范
密钥管理 支持本地密钥、KMS、HSM;默认使用临时密钥对(Keyless 模式) 支持本地密钥、KMS、HSM;不支持 Keyless 模式
公钥分发 通过 Sigstore 的 Rekor 透明日志或自定义公钥 通过信任存储(Trust Store)和信任策略(Trust Policy)管理
验证集成 支持 Kubernetes 动态准入控制(Cosign Webhook) 支持 Kubernetes 动态准入控制(Notation Admission Controller)
生态成熟度 社区活跃,与 GitHub Actions、GitLab CI 深度集成 CNCF 孵化项目,与 Azure、Docker 生态集成较好
签名算法 默认 ECDSA-P256,支持 RSA、Ed25519 默认 RSA-PSS,支持 ECDSA、Ed25519

3.2.1 选型建议

  • 优先选择 Cosign:如果你需要快速启动、希望利用 Keyless 模式降低密钥管理复杂度,或已使用 Sigstore 生态。
  • 优先选择 Notation:如果你所在组织已有成熟的 PKI 体系,需要严格遵循企业证书策略,或深度使用 Azure 云服务。
  • 混合使用:部分团队在开发环境使用 Cosign Keyless,在生产环境使用 Notation 结合 HSM 签名。

3.3 签名格式与存储位置

容器镜像签名并非直接修改镜像本身,而是将签名作为独立的 OCI 制品存储在容器镜像仓库中。这种设计保证了镜像的不可变性与签名的可分离性。

3.3.1 签名格式

Cosign 和 Notation 均遵循 OCI 制品规范,但签名内容的封装方式不同:

  • Cosign 签名格式:签名被封装为一个 OCI 制品,其 Manifest 中包含签名载荷、证书链(或公钥)以及镜像引用。签名制品的 MediaType 为 application/vnd.dev.cosign.simplesigning.v1+json。
  • Notation 签名格式:签名遵循 Notary 项目规范,使用 JWS(JSON Web Signature)格式封装签名、证书链和签名元数据。签名制品的 MediaType 为 application/vnd.cncf.notary.signature。
关键区别:Cosign 的签名载荷采用简单签名格式(Simple Signing),而 Notation 采用 JWS 标准格式。JWS 格式更通用,便于与其他 JOSE 生态工具集成。

3.3.2 存储位置

签名制品与原始镜像存储在同一个容器镜像仓库中,通过特定的标签或引用关联。具体存储策略如下:

工具 存储方式 示例引用
Cosign 在镜像 Digest 后追加 .sig 标签,或使用 OCI 引用规范 registry.example.com/my-image@sha256:abc... .sig
Notation 使用 OCI 引用类型(Referrers API),签名作为镜像的引用制品 registry.example.com/my-image@sha256:abc... (Referrer)

3.3.3 签名存储架构图

下图展示了签名制品与镜像在仓库中的关联关系:

签名存储架构图 签名制品与镜像的存储关联 容器镜像仓库 (Registry) 镜像 Manifest sha256:abc123... Cosign 签名制品 .sig 标签 / Referrer Notation 签名制品 JWS 格式 / Referrer 签名制品与镜像通过 OCI 引用规范关联,仓库支持按引用类型查询签名

3.3.4 签名验证流程

当准入控制器验证镜像签名时,执行以下步骤:

  1. 拉取镜像:获取镜像 Manifest 并计算摘要。
  2. 查询签名:通过 OCI Referrers API 或标签查找关联的签名制品。
  3. 解析签名:提取签名载荷、证书链或公钥。
  4. 验证签名:使用公钥解密签名,比对摘要是否一致。
  5. 检查信任链:验证证书链是否由受信任的根 CA 签发。
  6. 执行策略:根据签名验证结果决定允许或拒绝镜像运行。
安全警告:签名验证必须与信任策略(Trust Policy)配合使用。仅验证签名而不检查签名者身份,无法防止恶意镜像使用合法签名。务必配置允许的签名者列表或证书链。