国产 SM2 签名算法在 Cosign 中的插件扩展方法
解读
面试官通过该问题考察候选人三方面的深度:
- 对容器镜像签名生态(Cosign、Sigstore、OCI 规范)的掌握;
- 对国密算法 SM2/SM3 在 Linux 环境落地细节(包括 GM/T 0009、0010 规范)的理解;
- 在Docker 镜像供应链安全场景下,如何以“非侵入”方式把国密算法嫁接到国际开源工具,满足国内合规要求。
回答时要体现“能改代码、能写 Dockerfile、能落地 CI/CD”,而不是简单罗列文档。
知识点
- Cosign 的签名流程:generate-key-pair → sign → attach → verify,底层调用 go-fulcio 与 go-rekor;
- Cosign 支持PKCS#11 与 Hashicorp Vault 插件接口,但默认只带 ECDSA/P256、RSA、ED25519;
- SM2 属于ECC 椭圆曲线,曲线参数固定在 GM/T 0003.2-2012,OID 1.2.156.10197.1.301;
- 国密证书封装格式为SM2-with-SM3,签名值 DER 编码规则与 ECDSA 不同,需做 ASN.1 适配;
- 在容器环境,CGO 交叉编译常因 libssl、libgmalg 动态库导致镜像体积膨胀,需用多阶段构建静态链接;
- 国内合规要求私钥不出 HSM,因此插件必须走 PKCS#11 或国密 SKF 接口,而不是文件系统;
- 镜像签名后,Rekor 透明日志默认使用 SHA256,需扩展 pluggable type 字段,把 SM3 哈希写进 entry;
- 最终要在Harbor 或阿里云 ACR 的“策略-签名”检查环节,让验签端能识别新的 OID 与算法标识。
答案
我采用“Cosign 插件机制 + 国密动态库 + 多阶段构建”三步法,在不影响上游主干的前提下完成 SM2 支持。
-
编写签名器插件
在 Cosign 源码 pkg/signature/ 目录新增 sm2signer.Signer,实现 crypto.Signer 接口:- Sign 方法调用商密算法库(GmSSL 或江南科友 JNT PKCS#11 模块),完成 SM2-with-SM3 签名;
- 公钥序列化时把曲线 OID 写入 PKIX 扩展,使验签端能识别 SM2 椭圆曲线;
- 通过 Cosign 的 “--plugin” 参数注册到插件注册表,保持与原生 ECDSA 流程兼容。
-
构建轻量级签名镜像
Dockerfile 采用两阶段:- 阶段一基于 golang:1.21-alpine,安装musl-cross 与 GmSSL-dev,开启 CGO 静态编译:
CGO_ENABLED=1 GOOS=linux go build -tags=pkcs11,sm2 -ldflags '-linkmode external -extldflags "-static"' -o cosign-sm2 ./cmd/cosign - 阶段二拷贝到 distroless/cc 镜像,仅 25 MB,包含 libgmssl 静态库与 pkcs11 驱动,符合最小镜像安全原则。
- 阶段一基于 golang:1.21-alpine,安装musl-cross 与 GmSSL-dev,开启 CGO 静态编译:
-
集成到CI/CD 流水线
- GitLab CI 中声明变量 SM2_HSM_PIN,通过 Docker secret 挂载给 cosign-sm2 容器;
- 构建阶段完成
cosign-sm2 sign --key pkcs11:token=sm2-label --tlog-upload ${IMAGE_URI}; - 在Harbor 策略里增加“sm2”的算法白名单,验签端同样使用 cosign-sm2 verify,实现端到端国密合规。
落地后,镜像大小仅增加 8 MB,签名耗时 P95 从 90 ms 提升到 120 ms,满足金融级性能要求,并通过国密局商用密码产品二级认证现场测试。
拓展思考
- 如果未来 Sigstore 官方接受pluggable algorithm RFC,可以把 SM2 实现提交 upstream,避免长期维护私有分支;
- 考虑零信任网络,把 Rekor 透明日志也换成国密 SM3 哈希链,需要扩展 trillian-logserver 的哈希算法注册表;
- 在多集群联邦场景,可用 Docker Swarm 的“config”对象分发 sm2-pubkey.crt,实现集群级批量验签;
- 若客户要求混合算法,可让同一镜像同时携带 ECDSA 与 SM2 双签名,Cosign 的 OCI 索引层支持多 signature digest,验证逻辑只需轮询尝试;
- 最后,把上述流程固化成内部 Helm Chart,一键部署到麒麟 V10 或统信 UOS 容器平台,形成可复制的“国密容器签名”解决方案。