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)。私钥由签名者秘密保管,公钥可公开分发。签名流程如下:
- 签名者使用私钥对镜像摘要进行加密,生成签名。
- 验证者使用签名者的公钥解密签名,得到摘要 A。
- 验证者对镜像重新计算摘要 B,比较 A 与 B 是否一致。
若一致,则证明镜像未被篡改且确实由私钥持有者签名。
工程提示:私钥是签名体系中最敏感的资源。生产环境中应使用硬件安全模块(HSM)或密钥管理服务(KMS)存储私钥,避免私钥泄露导致信任体系崩塌。
3.1.3 数字签名流程示意图
下图展示了从镜像摘要计算到签名生成与验证的完整流程:
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 签名存储架构图
下图展示了签名制品与镜像在仓库中的关联关系:
3.3.4 签名验证流程
当准入控制器验证镜像签名时,执行以下步骤:
- 拉取镜像:获取镜像 Manifest 并计算摘要。
- 查询签名:通过 OCI Referrers API 或标签查找关联的签名制品。
- 解析签名:提取签名载荷、证书链或公钥。
- 验证签名:使用公钥解密签名,比对摘要是否一致。
- 检查信任链:验证证书链是否由受信任的根 CA 签发。
- 执行策略:根据签名验证结果决定允许或拒绝镜像运行。
安全警告:签名验证必须与信任策略(Trust Policy)配合使用。仅验证签名而不检查签名者身份,无法防止恶意镜像使用合法签名。务必配置允许的签名者列表或证书链。