4. 密钥管理基础:生成密钥对、理解私钥安全、公钥分发策略

在 Sigstore 体系中,密钥管理是构建信任边界的基石。无论是使用 Fulcio 颁发的短期证书,还是使用自管理的密钥对进行签名,理解密钥对的生成、私钥的安全存储以及公钥的分发策略,都是确保供应链安全的前提。本章将深入剖析这些基础操作与安全原则。

4.1 密钥对生成:从理论到实践

密钥对由私钥和公钥组成。私钥必须严格保密,用于对工件(如容器镜像、二进制文件)进行签名;公钥则公开发布,供验证方校验签名的真实性。Sigstore 支持多种密钥算法,推荐使用 ECDSA(P-256)或 Ed25519,因其在安全性与性能之间取得了良好平衡。

以下是使用 OpenSSL 和 Cosign 生成密钥对的典型命令:

# 使用 OpenSSL 生成 ECDSA P-256 私钥
openssl ecparam -genkey -name prime256v1 -noout -out private-key.pem

# 从私钥导出公钥
openssl ec -in private-key.pem -pubout -out public-key.pem

# 使用 Cosign 生成密钥对(推荐,自动处理格式)
cosign generate-key-pair
# 执行后会在当前目录生成 cosign.key(私钥)和 cosign.pub(公钥)
实践建议: 在生产环境中,优先使用 cosign generate-key-pair,因为它生成的密钥格式与 Sigstore 生态原生兼容,且支持密码保护。避免使用 RSA 4096 位以上的密钥,除非有严格的合规要求。

4.2 私钥安全:信任链的命门

私钥泄露意味着攻击者可以冒充合法发布者,对恶意工件进行签名。私钥安全必须遵循“最小权限、硬件隔离、定期轮换”三大原则。下表对比了不同私钥存储方式的安全等级与适用场景:

存储方式 安全等级 适用场景 风险点
文件系统(无加密) 低 本地开发测试 易被恶意软件窃取、误上传至代码仓库
文件系统(密码加密) 中 小团队 CI/CD 密码管理不当、内存转储泄露
云 KMS(AWS KMS / GCP Cloud KMS / Azure Key Vault) 高 企业级生产环境 依赖云服务商、需配置访问控制策略
硬件安全模块(HSM / YubiKey) 极高 高安全合规、根证书签名 成本高、管理复杂
安全红线: 永远不要将私钥文件(如 cosign.key)提交到 Git 仓库、打包进容器镜像或通过不安全的通道传输。一旦私钥泄露,应立即吊销对应的公钥信任,并重新生成密钥对。

4.3 公钥分发策略:建立信任锚点

公钥本身不敏感,但如何让验证方安全地获取正确的公钥,是信任链的关键。Sigstore 提供了多种公钥分发策略,各有优劣。下图展示了三种主流策略的架构对比:

公钥分发策略对比架构 策略1:带外分发 发布者通过 HTTPS、DNS 或 PGP 密钥服务器 手动分发公钥 策略2:透明度日志 公钥记录在 Rekor 日志中 验证方通过日志索引 查询公钥并验证 Merkle 证明 策略3:Fulcio 短期证书 Fulcio 签发 X.509 证书 证书链可在线验证 无需单独分发公钥 验证方:手动导入公钥 验证方:查询 Rekor 日志 验证方:验证证书链 策略选择建议 • 带外分发:适用于小团队或内部工具链,但存在公钥被篡改或中间人攻击的风险。 • 透明度日志:提供不可篡改的公钥审计记录,适合需要强溯源能力的场景。 • Fulcio 短期证书:Sigstore 推荐模式,通过 OIDC 身份绑定消除公钥分发问题,适合云原生 CI/CD。

4.4 密钥轮换与吊销

密钥轮换是降低长期密钥泄露风险的关键措施。建议遵循以下轮换周期:

  • 短期密钥(Fulcio 证书): 证书有效期通常为 10 分钟到 24 小时,由 Fulcio 自动管理,无需手动轮换。
  • 长期密钥(自管理): 建议每 90 天轮换一次。轮换时,需使用新私钥重新签名所有活跃工件,并更新公钥分发点。
  • 吊销: 当私钥泄露或员工离职时,应立即吊销对应公钥。在 Sigstore 中,可通过将公钥指纹加入吊销列表(CRL)或更新信任策略来实现。
关键实践: 使用 cosign verify 时,通过 --key 参数指定公钥文件,或通过 --cert 和 --cert-chain 验证 Fulcio 证书链。对于自管理密钥,建议将公钥存储在安全的配置管理服务(如 Vault)中,并定期同步到验证环境。

4.5 实战:使用 Cosign 完成密钥生命周期管理

以下是一个完整的密钥生命周期管理示例,涵盖生成、签名、验证和轮换:

# 1. 生成密钥对(带密码保护)
cosign generate-key-pair
# 输入密码,生成 cosign.key 和 cosign.pub

# 2. 使用私钥签名容器镜像
cosign sign --key cosign.key your-registry/your-image:tag

# 3. 验证签名(使用公钥)
cosign verify --key cosign.pub your-registry/your-image:tag

# 4. 密钥轮换:生成新密钥对
cosign generate-key-pair
# 输入新密码,生成新的 cosign.key 和 cosign.pub

# 5. 使用新私钥重新签名
cosign sign --key cosign.key your-registry/your-image:tag

# 6. 更新验证方的公钥配置
# 将新的 cosign.pub 内容更新到验证策略中
注意: 密钥轮换后,旧签名仍然有效,只要旧公钥未被吊销。建议在轮换后保留旧公钥一段时间(如 30 天),确保所有已签名的工件仍可被验证。之后再将旧公钥从信任列表中移除。