国密算法概述:SM2/SM3/SM4 背景与应用场景

各位同学,咱们直接进入正题。国密算法,说白了就是咱们国家自己制定的密码标准。为什么要搞一套自己的?你可以想想,如果金融、政务这些核心系统全跑在别人家的算法上,风险是不是有点大?所以从 2010 年开始,国家密码管理局陆续发布了 SM2、SM3、SM4 等一系列算法标准。我最早接触国密是 2016 年做银行项目,那会儿刚起步,很多库写得还不成熟,踩坑踩到怀疑人生。不过现在好多了,生态越来越完善。

这一章我们先从整体上认识这三个算法。不涉及具体代码,但很重要——你得知道它们各自能干什么、不能干什么,才能在架构设计里选对工具。

SM2:国密体系的公钥担当

SM2 是一套基于椭圆曲线密码学(ECC)的公钥密码算法。它主要干三件事:

  • 数字签名——确认身份,防止抵赖。
  • 密钥交换——双方安全地协商出一个只有彼此知道的密钥。
  • 公钥加密——用公钥加密,私钥解密。

和咱们熟悉的 RSA 比,SM2 的密钥更短,性能却更高。举个例子,SM2 用 256 位的密钥长度,就能达到 RSA 2048 位的安全强度。我在项目中做过压测,同样是签名操作,SM2 比 RSA 快大概 3 到 5 倍。所以你想想看,在高并发场景下选谁更划算?

特性 SM2 RSA
算法类型 椭圆曲线(ECC) 大整数分解
密钥长度(推荐) 256 位 2048 位
签名性能 高 中
国内标准号 GB/T 32918 无(国际标准)
我的一点经验:SM2 的密钥对生成时需要指定曲线参数。国标里用的是 sm2p256v1 曲线,不要搞混了。我曾经见过有人把 NIST 曲线参数配进 SM2 的库,结果签名验签怎么都对不上——这种事排查起来特别痛苦。

SM2 在政务、金融、CA 证书系统里用得最多。比如电子发票的签章、银行的 U 盾认证,背后基本都是 SM2。

SM3:数据完整性的守门员

SM3 是密码杂凑算法,简单说就是给一段数据算出一个固定长度(256 位)的摘要。它有这些核心特性:

  • 单向性——从摘要几乎不可能反推出原始数据。
  • 抗碰撞——很难找到两段不同的数据,它们的摘要相同。
  • 固定输出——不管输入多大,输出永远是 256 位。

这就好比给每个文件做了一张“数字指纹”。你下载一个软件包,用 SM3 算出摘要,和官网公布的对比一下,如果一样,说明文件没被篡改过。

SM3 的算法结构其实参考了 SHA-256,但做了针对性优化。我在对比过两者的软件实现,SM3 在国密体系里天然兼容 SM2 和 SM4,集成起来更顺手。如果你只是在内部系统用 SM3,完全不用担心安全问题——到目前为止,它还没被公开破解过。

常见应用场景:

  • 文件完整性校验。
  • 数字签名中的摘要生成(配合 SM2)。
  • 密码存储(虽然更推荐用 bcrypt 或 argon2,但有些强制国密场景不得不用 SM3 + 盐)。
注意:SM3 不是加密算法,是哈希算法。不能把秘密数据直接“用 SM3 加密”存起来,这个说法不严谨。哈希只是一条单行道。

SM4:对称加密的主力军

SM4 是对称分组密码算法,说白了就是加密和解密用同一把钥匙。它最常用的地方是**数据加解密**和**通信链路加密**。

SM4 的分组长度是 128 位,密钥长度也是 128 位。它支持 ECB、CBC、CTR、GCM 等多种工作模式。我个人建议,能选 GCM 就别选 ECB。ECB 模式的安全隐患,我在一次数据脱敏项目里吃过亏——同样的明文块会加密成同样的密文块,给攻击者留下了统计分析的空间。

模式 特点 推荐度
ECB 简单,但相同明文块产生相同密文 不推荐
CBC 需要初始化向量(IV),加密结果受前一个分组影响 通用
GCM 自带认证标记,能检测篡改 强烈推荐

SM4 的运算速度非常快,在硬件和软件上都有不错的实现。比如做视频流加密、数据库字段加密,SM4 都是首选。

为什么要把这三个算法放在一起学?

答案很简单:**它们天然是搭档**。你想想一个典型的加密通信流程:

  1. 方用 SM2 公钥加密一个临时通信密钥(对称密钥)。
  2. 接收方用 SM2 私钥解密,拿到这个临时密钥。
  3. 双方用 SM4 对这个临时密钥进行对称加密通信。
  4. 每一条消息再用 SM3 计算摘要,附上 SM2 签名,保证完整性。

这就构成了“SM2 密钥交换 + SM4 数据加密 + SM3 完整性校验”的闭环。你在做 Go 语言国密 SDK 封装时,会发现这三个库经常需要互相调用。比如 SM2 签名前要先调用 SM3 计算摘要,SM4 的密钥可以是从 SM2 密钥交换中协商出来的。

核心理解:SM2 管身份和密钥交换,SM3 管完整性,SM4 管加密效率。缺少任何一个,都不算完整的国密安全方案。

好,接下来我们用一张图把这些关系理清楚。这张图展示了一个典型的国密体系结构,以及各算法之间的调用关系。

国密算法体系及核心交互流程 国密算法体系 SM2 公钥密码 数字签名 密钥交换 公钥加密 SM3 密码杂凑 数据摘要 完整性校验 SM4 对称密码 数据加密 链路加密 数字签名 / CA 金融、政务、电子合同 完整性保护 文件校验、区块链 数据加密通信 API 加密、数据库加密 SM3 摘要 → SM2 签名 SM2 密钥交换 → SM4 密钥 典型组合:SM2 交换密钥 + SM4 加密数据 + SM3 保证完整 三个算法缺一不可,共同构成完整的国密安全方案
实用建议:当你开始写 Go 代码封装国密 SDK 时,优先把 SM3 封装好——因为 SM2 和 SM4 在 API 设计上都会依赖 SM3 的摘要函数。我习惯先写一个 sm3utils 包,里面放好基础计算、文件摘要、HMAC 这些方法,后面就顺手了。

说了这么多,我想你应该能感觉到,国密算法并不是什么神秘的东西。它和主流国际算法在思路上一脉相承,只是在曲线参数、S 盒、轮函数这些底层细节上做了自主设计。只要你的 Go 开发经验够,把 SM2/SM3/SM4 用好、封装好,并不是一件难事。

好,第一章就到这里。先把这三个算法的定位和关系刻在脑子里,后面我们动手写代码的时候,你会发现自己思路特别清晰。