国密算法实战指南:SM2、SM3、SM4 怎么选、怎么对接、怎么排查
国密不是可选项,是硬性合规
做政务、金融、国企项目的开发者迟早撞上同一句话:「系统需支持国密算法」。这不是技术偏好——等保 2.0 和商用密码评估(密评)把 SM 系列算法写进了验收标准,SHA-256 和 RSA 在这些场景不能替代 SM3 和 SM2。第一次对接时最容易犯的认知错误是拿国际算法类比硬套:「SM3 就是中国的 SHA-256 吧?」——设计上确实同构,但两端必须跑同一套算法才能对上:你用 SHA-256 算的摘要发给要求 SM3 的对端,永远校验失败。
三个算法各管一摊,选型一句话:
| 需求 | 算法 | 国际对应 | |---|---|---| | 数据加密(对称) | SM4 | AES | | 哈希/摘要 | SM3 | SHA-256 | | 签名/非对称加密 | SM2 | RSA/ECC |
配套的浏览器本地工具:SM4 加解密、SM3 哈希、SM2 加解密签名——联调时快速造测试数据、验证中间结果,全程不上传。
SM4:对接失败 90% 死在这三处
SM4 是 128 位分组密码,对接时「我加密的对端解不开」的排查顺序(按命中率排):
1. 密钥格式。SM4 密钥固定 16 字节,联调最常见的错位是:你用 UTF-8 字符串直接当密钥("1234567890abcdef" 被当 16 个字符),对端按 32 位 hex 解析成 16 字节——同一个字符串,两种解释,密文必然不同。确认双方约定:hex 还是 utf8 直填,长度按字节算不是按字符算。
2. 工作模式与 IV。ECB 无 IV、CBC 必须带 16 字节 IV 且两端一致。模式错配的典型症状是:解密不报错但明文是乱码(前 16 字节对、后面全错——IV 错位的高频指纹)。真实业务应避开 ECB(相同明文块产出相同密文块,泄漏结构特征),测试连通性时才用它。
3. 输出编码。密文用 hex 还是 base64 传输,三方(你、对端、文档)必须写死同一个约定。这个排最后不是因为少见,是因为一旦约定了就不容易错——前提是真的约定了。
一个健康的调试习惯:联调前双方先用固定明文 + 固定密钥各出一份期望密文,肉眼比对不一致再逐项对上面三处,比对着黑盒猜快十倍。
SM3:哈希的「对不上」只有一种原因
SM3 输出固定 256 位(64 个 hex 字符)。它没有密钥、没有模式、没有 IV——所以两端算出来不一样时,原因只有一个:输入不一样。而输入不一样的头号惯犯是不可见字符:
- 文档里复制出来的字符串带尾随换行或空格
- 一端做了 trim 另一端没做
- JSON 序列化的字段顺序或空格差异(对 JSON 做 SM3 摘要前必须约定规范化序列化)
- 编码差异:UTF-8 vs GBK 对中文输入产出完全不同的哈希
排查法:把双方的原始输入按字节打出来(hex dump)对比,而不是对比字符串看着像。哈希算法本身没有「兼容性问题」——它是确定性的,输入相同输出必然相同,所以 SM3 对不上 = 输入不同,没有第二种可能。
SM2:三件事别搞混
SM2 是椭圆曲线体系,一次对接里通常出现三种操作,别混:
- 加密/解密:公钥加密、私钥解密(给别人传敏感数据时用)
- 签名/验签:私钥签名、公钥验签(证明「这是我发的、没被改过」)
- 密钥协商:双方推导共享密钥(通信建连时用,工具里一般不涉及)
高频坑:验签失败的真正原因往往不在签名算法,而在被签名的原文——两端对「签名内容」的理解不一致(一端签的是原始报文,另一端验的是去掉换行的版本,或加了字段名前缀的版本)。排查顺序:先逐字节比对双方的待签原文,再看密钥对是否匹配。
密钥安全边界必须说清:测试密钥随便造(SM2 工具本地生成一对,加密→解密、签名→验签闭环验证流程),生产私钥永远不进任何网页、脚本参数或聊天工具——私钥管理属于密管系统/硬件加密机的职责,不属于联调工具。
一张联调自查表
| 症状 | 先查 | |---|---| | SM4 密文对端解不开 | 密钥解释(hex/utf8)→ 模式与 IV → 输出编码 | | SM4 解密出乱码但首块正常 | IV 错位(CBC 的经典指纹) | | SM3 两端哈希不一致 | 不可见字符 / trim / 编码(输入必然不同) | | SM2 验签失败 | 待签原文逐字节比对 → 密钥对匹配 | | 全部对不上 | 先用固定明文+固定密钥交换期望密文基线 |
与国际算法并存的现实
多数系统在过渡期需要同时支持两套:配置里留算法开关(algorithm: SM4 | AES),按对接方的要求逐通道切换。工具层面两端都备齐:国密三件套之外,站内同样有 AES 加解密、RSA 工具和 SHA-256——同一份数据两套算法各算一遍比对,是过渡期排查的日常。
本文工具均来自 ToolVault——166 个开发者工具,全部浏览器本地运行,密钥与数据不出设备。