SM3算法概述
做密码学这么多年,我接触过不少哈希算法。但第一次看到SM3时,心里挺感慨的——终于有一套咱们自己的标准,不再什么都靠别人了。这一章咱们聊聊SM3从哪里来,它怎么被国家定下来的,再顺手跟SHA-256掰掰手腕。
SM3算法背景
SM3是国密系列里的哈希算法,全称叫SM3密码杂凑算法。2010年国家密码管理局正式发布,2016年升格为国家标准。它的核心任务就是给任意长度的数据“算指纹”——固定输出256位(32字节)的杂凑值。
为什么要有SM3?说白了就两个字:可控。之前很多系统用的SHA-1、SHA-256都是美国标准,万一哪天人家不让用了呢?我在做政务系统时,客户明确要求“必须用国密”,那时候SM3已经成熟,直接拿来用就行。这种需求现在越来越多。
- 设计年份:2010年发布,2016年国标GB/T 32905-2016
- 输出长度:256位(32字节)
- 基础结构:Merkle-Damgård结构 + 压缩函数
- 安全强度:与SHA-256相当,抗碰撞能力128位
国密标准体系
国密不是只有SM3一个算法。它是一个完整的密码家族。我列个表,大家能看得更清楚。
| 算法 | 类型 | 标准编号 | 典型用途 |
|---|---|---|---|
| SM1 | 对称加密 | 内部标准 | 芯片级加密,不公开算法 |
| SM2 | 公钥密码 | GB/T 32918 | 数字签名、密钥交换 |
| SM3 | 哈希算法 | GB/T 32905 | 完整性校验、数字签名辅助 |
| SM4 | 对称加密 | GB/T 32907 | 数据加密(替代AES) |
| SM9 | 标识密码 | GB/T 38636 | 基于标识的密码系统 |
这里要留意一点:SM3经常和SM2配合使用。数字签名时,先拿SM3把消息算成摘要,再用SM2签名。两者是绑定关系,不能用SHA-256代替SM3,否则就不算合规。
与SHA-256对比
SHA-256是国际通用的哈希标准,SM3在很多方面都参考了它,但做了不少调整。我挑几个关键差异说说。
| 对比项 | SM3 | SHA-256 |
|---|---|---|
| 消息分组大小 | 512位(64字节) | 512位(64字节) |
| 字长 | 32位 | 32位 |
| 消息扩展 | 132字(W₀~W₆₇,W'₀~W'₆₃) | 64字(W₀~W₆₃) |
| 压缩函数轮数 | 64轮 | 64轮 |
| 初始值(IV) | 固定常量(不同于SHA-256) | 固定常量 |
| 布尔函数 | 4个(GG, GG', FF, FF') | 3个(Ch, Maj, Σ) |
| 移位/循环移位 | 多种移位组合 | 循环右移为主 |
| 性能(软件) | 略慢于SHA-256(约慢5-10%) | 较快 |
从安全上看,两者目前都没有实际有效的碰撞攻击。SM3在设计时修复了一些SHA-2家族的理论弱点(比如扩展函数的扩散性更好),但实战差距不大。我个人建议:国内合规场景无脑选SM3,国际互通场景才考虑SHA-256。
SM3整体流程(一张图看懂)
下面这张图展示了SM3从输入消息到输出杂凑值的完整流程。嗯,我故意把消息扩展和压缩函数分开画,方便大家理解分层。
这张图里的“迭代处理”是重点。每个分组都会经过消息扩展和64轮压缩函数,最终得到256位的状态值。我个人经常把这比作“搅拌机”——每轮都加不同的调料,最后出来的就是独一无二的指纹。
避坑与建议
- 不要自己实现SM3:算法细节多,移位操作容易出错。哪怕你读懂了标准,也别在生产环境手写。调用国家密码局认证的库或者OpenSSL(版本≥1.1.1)就行。
- 注意大端小端:SM3处理时用的是大端序(Big-Endian),和x86 CPU的小端相反。我在做嵌入式移植时吃过这个亏——算出来的摘要老和标准库不一样。
- 别和SHA-256混用:同一个系统里尽量统一用国密或用国际标准。混用会增加审计复杂度,而且一旦出了安全问题,两边你都得修。
1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b。我每次换库版本都会先跑一遍这个向量。
好了,SM3的出身、标准、和SHA-256的对比都聊完了。说白了,它就是咱们国家的哈希“标配”,安全够用、生态在壮大。下一块咱们就要钻进它的内部看细节了——消息扩展和压缩函数的每一轮是怎么算的,我会掰开揉碎讲明白。