「我们是不是要上国密」这个问题,在国内做后端的大概都被问过。回答它需要先分清两件事:这三个算法各是什么,以及谁真的被要求用。
对标关系:一张表看清
| 国密 | 类型 | 对标 | 关键参数 |
|---|---|---|---|
| SM2 | 椭圆曲线公钥算法 | ECDSA / ECDH(P-256) | 256 位素域曲线,含签名、密钥交换、公钥加密 |
| SM3 | 杂凑算法 | SHA-256 | 256 位输出 |
| SM4 | 分组密码 | AES-128 | 128 位分组,密钥只有 128 位 |
有两点值得强调:
安全强度是同一量级。 SM2 大致等价于 RSA-3072,SM3 的目标和 SHA-256 对齐,SM4 对应 AES-128。选国密的理由是合规,不是安全性上有代差——「用了国密就更安全」是个常见误解。
SM4 只有 128 位密钥。 AES 有 128/192/256 三档,SM4 没有。标准里不存在「SM4-256」,看到这个说法基本可以判定对方搞错了。
标准编号速查
每个算法都有一份行业标准(GM/T)和一份国家标准(GB/T),内容一致,编号不同:
| 算法 | 行业标准 | 国家标准 |
|---|---|---|
| SM2 | GM/T 0003-2012(5 个部分) | GB/T 32918 系列(5 个部分) |
| SM3 | GM/T 0004-2012 | GB/T 32905-2016 |
| SM4 | GM/T 0002-2012 | GB/T 32907-2016 |
SM2 的五个部分分别是:总则、数字签名算法、密钥交换协议、公钥加密算法、参数定义。
还有一份很关键但常被忽略的:
GM/T 0009-2012《SM2 密码算法使用规范》
密文的 C1C3C2 排列顺序、ASN.1 编码结构,都规定在这里,不在算法标准里。对接时真正会耗掉你半天的细节,全在这一份——详见 SM2 密文和签名对不上的四个原因。
这三个算法都已被纳入 ISO/IEC 的相关标准,不再是只有国内认的算法。但国际生态的实际支持度仍然远不如 AES 和 SHA-2,这一点在选型时要考虑。
谁真的需要国密
明确需要的:
- 党政机关信息系统
- 关键信息基础设施 —— 能源、金融、交通、水利、公共通信、电子政务等领域的重要系统
- 需要通过商用密码应用安全性评估(密评)的系统 —— 判据是 GB/T 39786《信息安全技术 信息系统密码应用基本要求》
- 特定行业业务 —— 电子政务电子认证、金融行业的部分业务,各行业主管部门另有细则
通常不需要的:
- 面向普通消费者的互联网产品
- 企业内部办公系统
- 不涉及上述领域的商业软件
这些用 AES 和 SHA-2 完全合规。
判断方法:去问合规或安全团队「本系统是否在密评范围内」,而不是自己按规模或重要性推测。具体要求以现行法规和主管部门的最新文件为准,这块的口径会随文件更新变化。
性能:差距来自指令集,不是算法
这是最容易被纸面参数误导的一项。
SM4 和 AES 的算法复杂度接近,但实测常常明显慢于 AES。 原因不在算法设计,在硬件:
- 现代 x86 CPU 有 AES-NI 指令集,ARM 有 Crypto Extensions——AES 在有硬件加速时能快出一个数量级
- SM4 的硬件支持要少得多,多数环境下只能走纯软件路径
SM3 同理,SHA-256 也有专用指令。
SM2 相对好些:签名验签的开销和 ECDSA 相当,比 RSA-2048 快,这一项通常不是瓶颈。
三条实务建议:
- 大批量数据加密前先做压测,别按算法的纸面性能规划容量
- 有条件时用支持国密的硬件密码模块或加密卡——这在密评场景下本来也常是要求
- 前端不要放大数据量的国密运算(原因见下)
生态:Java 最成熟,浏览器端有硬约束
| 环境 | 情况 |
|---|---|
| Java | BouncyCastle 1.57 起支持较完整,事实上的首选 |
| C / C++ | GmSSL,国内维护的 OpenSSL 分支,功能完整 |
| Go | 若干社区实现,质量参差,需甄别 |
| Python | 多个第三方包,同样需甄别 |
| 浏览器 | Web Crypto API 不支持国密,只能用纯 JavaScript |
最后一行是个硬约束:浏览器原生一个国密算法都没有。这意味着前端做国密的性能天然受限——纯 JS 实现比原生慢得多,大数据量场景不要放在前端。
选库时的检验方法很简单:拿标准里的官方测试向量跑一遍。SM3 的向量在 GM/T 0004 里,SM4 的在 GB/T 32907 里,都是公开的,几分钟就能验完。通不过官方向量的库直接排除——这类库在国密生态里确实存在。
能不能和国际算法混用
技术上完全可以。 这些算法之间没有耦合:可以用 SM2 做密钥交换、AES 加密数据,也可以 SM4 加密、SHA-256 做摘要。
混合加密的结构也一样适用——用 SM2 加密一把 SM4 密钥,和用 RSA 加密 AES 密钥是同一个套路,也同样是因为公钥算法不适合直接加密大数据。
合规上要看具体要求。 如果系统在密评范围内,混用可能不满足要求:密评关注的是整条密码链路的合规性,出现非国密算法很可能被判不合规。
实务上:
- 密评范围内:整条链路统一国密,包括传输、存储、签名、认证
- 范围外:按技术需要选,不必强行国密化
- 过渡期:常见「双算法」方案,同时支持两套,按对端能力协商
具体口径以评估机构和主管部门的要求为准。
上手先跑一遍官方向量
国密 SM2/SM3/SM4 三个算法都做了:
- SM4 对称加解密,支持 ECB / CBC / GCM 和 PKCS7 填充
- SM2 公钥加解密、签名验签、密钥对生成,密文排列和编码格式可选
- SM3 摘要和 HMAC
实现基于 sm-crypto-v2,SM3 用 GM/T 0004 的官方测试向量验证,SM4 用 GB/T 32907 的官方向量验证,全部在浏览器本地计算,密钥不上传。
它最实用的场景是给自己的实现做基准:选好库之后,拿同一组输入在两边各跑一遍,结果一致才说明库是可信的。这一步花几分钟,能省掉后面几天的怀疑人生。