国产 SM2 签名算法在 Cosign 中的插件扩展方法

解读

面试官通过该问题考察候选人三方面的深度:

  1. 容器镜像签名生态(Cosign、Sigstore、OCI 规范)的掌握;
  2. 国密算法 SM2/SM3 在 Linux 环境落地细节(包括 GM/T 0009、0010 规范)的理解;
  3. 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 支持。

  1. 编写签名器插件
    在 Cosign 源码 pkg/signature/ 目录新增 sm2signer.Signer,实现 crypto.Signer 接口:

    • Sign 方法调用商密算法库(GmSSL 或江南科友 JNT PKCS#11 模块),完成 SM2-with-SM3 签名;
    • 公钥序列化时把曲线 OID 写入 PKIX 扩展,使验签端能识别 SM2 椭圆曲线;
    • 通过 Cosign 的 “--plugin” 参数注册到插件注册表,保持与原生 ECDSA 流程兼容。
  2. 构建轻量级签名镜像
    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 驱动,符合最小镜像安全原则
  3. 集成到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 容器平台,形成可复制的“国密容器签名”解决方案。