cosign generate 默认生成 ecdsa p-256 密钥对,私钥为 pem 格式(cosign.key),公钥为 der 编码(cosign.pub);私钥需 chmod 0600,公钥 verify 仅认 der 格式。

cosign generate 生成的密钥对长什么样
默认用 cosign generate 生成的是 ECDSA P-256 密钥对,私钥存为 PEM 格式(cosign.key),公钥是 DER 编码的 cosign.pub ——注意不是 PEM,不能直接用 cat 看内容,会乱码。
- 私钥文件必须严格保密,权限建议设为
0600;误设成0644会导致cosign sign拒绝使用 - 公钥文件虽可公开,但
cosign verify默认只认 DER 格式;若你手动生成 PEM 公钥(比如用openssl转换),verify 会报错failed to load public key: unable to parse key - 不推荐用
--kms或--azure-kv等托管方式初学,本地文件流程最可控,也最能暴露权限和路径问题
cosign sign 怎么指定私钥和签名目标
cosign sign 必须显式传入私钥路径(-key)和待签名镜像或文件(支持 OCI 镜像、二进制、目录等),它不会自动找 cosign.key,也不会读环境变量。
- 镜像签名示例:
cosign sign -key cosign.key ghcr.io/user/app:v1.2.0 - 文件签名示例:
cosign sign-blob -key cosign.key ./release.tar.gz(注意函数名是sign-blob,不是sign) - 如果私钥路径写错或权限不足,错误信息是
error: signing with key: open /xxx/cosign.key: permission denied,不是“file not found” - 签名过程依赖远程 registry 支持 OCI Artifact,GitHub Container Registry 和 GHCR 默认支持;Docker Hub 不支持,会卡在
pushing signature并最终超时
cosign verify 失败的三个高频原因
90% 的 cosign verify 失败不是密钥问题,而是上下文不匹配:镜像 digest、registry 地址、公钥格式三者必须严丝合缝。
- 别用 tag 验证:
cosign verify -key cosign.pub ghcr.io/user/app:v1.2.0很可能失败,因为 tag 可能被覆盖;务必用 digest:cosign verify -key cosign.pub ghcr.io/user/app@sha256:abc123... - 公钥路径写错或格式不对,错误提示是
failed to load public key: asn1: structure error—— 这几乎等于你在用 PEM 格式公钥,而 cosign 要 DER - 本地没配 registry auth(比如用
docker login登录过 GHCR),verify 会卡住几秒后报GET https://ghcr.io/v2/.../manifests/...: DENIED: permission denied,不是密钥问题,是鉴权缺失
工作流模板里最容易漏掉的一行
所有自动化脚本(CI/CD 或本地发布)中,cosign sign 后必须跟 cosign verify,且 verify 命令里的 digest 必须来自 sign 输出的最后一行,不能靠 docker inspect 或 skopeo 二次查 —— 因为 sign 完立即 push,中间可能有并发覆盖。
- 正确做法:用命令替换捕获 digest,例如:
digest=$(cosign sign -key cosign.key ghcr.io/user/app:v1.2.0 | grep "Pulled" | awk '{print $NF}')<br>cosign verify -key cosign.pub ghcr.io/user/app@$digest - 如果你用
cosign sign --yes跳过确认,输出里 digest 行依然存在,不影响提取 - 这个 digest 是签名 artifact 的 digest,不是镜像本身的 digest;两者不同,不能混用










