第1章 国密算法概述:SM2、SM3、SM4 算法与合规性

做接口集成这么多年,我碰到最头疼的事之一,就是跟国际算法打交道——RSA 密钥太长,AES 性能还行但总担心后门。后来国密标准推开了,实测下来,其实没那么神秘。说白了,国密就是国家密码管理局推荐的一套商用密码算法族,核心是 SM2、SM3、SM4。你如果要在政务、金融、能源这些行业做 CI/CD 集成,躲不开它们。

先记住一句话:SM2 是非对称、SM3 是哈希、SM4 是对称。下面我一个个讲,顺带聊聊我踩过的坑。

SM2 算法——椭圆曲线公钥密码

SM2 对标的是 RSA 和 ECDSA。我习惯用它做签名验签和密钥协商。最早在项目中换 SM2 时,有个坑:很多老旧库只支持 P-256 曲线,不支持 SM2 的国密曲线(参数不一样)。所以集成 CI/CD 时,一定要确认依赖库的版本——比如 OpenSSL 1.1.1 及以上才原生支持 SM2,且必须指定 SM2 曲线名,不是 prime256v1。

特性SM2RSA-2048
密钥长度256 位2048 位
签名长度64 字节256 字节
计算性能快(约 2~3 倍 RSA)较慢
安全强度256 位 ≈ RSA 30722048 位

个人习惯:在做 CI/CD 的密钥分发步骤时,我会把 SM2 私钥用 KMS 托管,流水线只拿公钥签名验证。避免私钥明文出现在构建日志里——我以前吃过这个亏,日志一打印,密钥全裸了。

SM3 算法——密码杂凑函数

SM3 输出 256 位哈希值,和 SHA-256 长度一致,但算法细节不同。项目中我主要用它做数据完整性校验和数字签名中的摘要。

曾经在一个国密改造项目里,我直接拿 SM3 替换 SHA-256,结果发现依赖的签名验证库对 SM3 的 OID 不认识,一直报 “unsupported hash”。后来查规范才知道,SM3 的 OID 是 1.2.156.10197.1.401,得手动注册进 JCA Provider 才行。嗯,这个细节我记了好几年。

// 使用 BouncyCastle 计算 SM3 摘要(Java)
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import org.bouncycastle.crypto.digests.SM3Digest;

Security.addProvider(new BouncyCastleProvider());

SM3Digest digest = new SM3Digest();
byte[] input = "国密CI/CD集成".getBytes("UTF-8");
digest.update(input, 0, input.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash, 0);
// hash 即为 32 字节的 SM3 杂凑值

注意:SM3 不等于 SHA-256!不要以为长度一样就能直接互换。SM3 的填充方式和压缩函数不同,混用会导致签名验签失败。

SM4 算法——分组对称密码

SM4 是对称加密,128 位密钥,128 位分组,类似 AES。我常拿它加密接口报文里的敏感字段,比如手机号、身份证号。性能很好,软实现也能跑几百 MB/s。

在做 CI/CD 流水线时,我建议把 SM4 密钥通过环境变量注入,不要硬编码在代码里。之前有个同事直接把 sm4Key = “1234567812345678” 写在业务代码里,代码推送到 Git 仓库后被扫描工具报了违规……尴尬。

模式说明推荐场景
ECB电子密码本,不安全不推荐
CBC密文分组链接,需 IV通用加密
GCM带认证的加密模式要求完整性校验时

核心:国密合规不仅仅是用对算法,还涉及密钥生命周期管理、协议栈(如 SSL 国密套件 TLS 1.3 国密版)、以及 API 是否经过国密型号认证。CI/CD 中,你要在编译阶段就引入国密库,避免后期替换时出现兼容性问题。

国密标准与合规性要求

国密算法对应的标准号如下,集成时建议对照查阅最新版(以 GM/T 系列为准):

算法标准号状态
SM2GM/T 0003-2012现行
SM3GM/T 0004-2012现行
SM4GM/T 0002-2012现行(已更新 2022)

合规性要求方面,我接触过的几个关键点:

  • 必须使用国家密码管理局认证的密码模块(如 SJ/T 11679 或 GM/T 0054 检测通过的产品)
  • 密钥生成需在硬件安全模块(HSM)或安全环境中完成,不能在纯软件里拍脑袋随机
  • CI/CD 流水线中涉及密码操作的阶段(如签名、加密)应记录日志,以备等保测评审查
  • 禁止使用自实现的国密算法——哪怕你觉得自己写得再漂亮,没有检测认证也是违规

下面这张图,是我自己梳理的国密算法体系与 CI/CD 集成阶段的关联,你一看就明白它怎么嵌进你的流水线里。

国密算法体系及 CI/CD 集成映射 SM2 非对称 SM3 哈希 SM4 对称 签名 / 密钥协商 完整性校验 数据加密 CI/CD 集成关键环节 🔑 密钥注入 🔒 签名/验签步骤 📋 合规日志

避坑经验:我曾经在一个容器化 CI/CD 项目里,用官方 OpenSSL 镜像做 SM2 签名,结果发现镜像是 1.1.0 版本,根本不支持国密曲线。后来改用 registry.cn-hangzhou.aliyuncs.com/xxx/gmssl 镜像才搞定。所以流水线里用的基础镜像,一定要显式验证国密库版本,不能偷懒用默认最新。