2. SM3 算法概述
哈希函数,说白了就是给任意长度的数据打一个“数字指纹”。你输入一段文字、一张图片,甚至一个几百 MB 的文件,它都能给你算出一个固定长度的摘要。这个摘要几乎不可能反向还原出原文——对,这就是单向性。
我刚开始接触密码学的时候,总觉得哈希不就是个校验和吗?后来被项目坑过一次才明白:校验和(比如 CRC)是专为错误检测设计的,哈希函数得扛得住恶意碰撞攻击。你想想看,攻击者要是能故意造出两个不同文件却拥有同一个哈希值,那签名、证书就全废了。
2.1 哈希函数原理
一个合格的哈希函数,必须满足三个核心性质:
- 单向性(Preimage Resistance):给定
y = H(x),几乎不可能找到任何x'使得H(x') = y。说白了,就是只能正向算,不能反向推。 - 第二原像抗性(Second Preimage Resistance):已知
x和y = H(x),几乎不可能找到另一个x' ≠ x使得H(x') = y。 - 碰撞抗性(Collision Resistance):找不到任意两个不同的
x1, x2使H(x1) = H(x2)。
为什么第三点特别重要?我举个例子:你在证书上签名,签的是哈希值。如果有人能造出两份不同合同但哈希值相同,就能拿一份合法的合同去申请签名,然后用另一个恶意版本去骗人。嗯,这叫碰撞攻击,SM3 的设计里特别考虑了这一点。
2.2 SM3 国家标准(GM/T 0004)
SM3 是国密标准里的哈希算法,全称叫“GM/T 0004-2012 SM3 密码杂凑算法”。它是中国国家密码管理局在 2012 年发布的,后来 2016 年更新过一版。标准里规定了算法步骤、初始值、常量、消息填充方式、迭代压缩函数,甚至给了一份 C 参考实现。
我在做金融系统国密改造时,发现很多同事会把 SM3 和 SHA-256 混用,觉得“反正都是 256 位输出”。其实不对——SM3 的压缩函数结构和 SHA-256 差异很大,安全边界也不一样。
2.3 SM3 算法核心流程
SM3 的处理流程大体分三步:
- 消息填充:先在消息末尾加一个 1 bit,再加若干个 0 bit,使消息长度模 512 等于 448。最后附加 64 bit 的原始消息长度(大端序)。
- 消息分组:填充后的消息按 512 bit(64 字节)一组分成
B0, B1, ..., Bn-1。 - 迭代压缩:每一组经过 64 轮压缩,更新 256 bit 的中间状态,最终输出 256 bit 摘要。
0x7380166f, 0x4914b2b9, ...。可以在标准文档里查到。
2.4 SM3 与 SHA-256 的对比分析
很多同学问我:“直接用 SHA-256 不行么?SM3 有什么特别的?” 我的回答是:两者都是 256 位哈希,但设计细节和安全性不同。咱们直接看对比表:
| 对比维度 | SM3 (GM/T 0004) | SHA-256 (FIPS 180-4) |
|---|---|---|
| 输出长度 | 256 bit | 256 bit |
| 消息块大小 | 512 bit | 512 bit |
| 轮数 | 64 轮 | 64 轮 |
| 压缩函数结构 | 类 ARX + 布尔函数 | 类 ARX |
| 布尔函数 | FF, GG 四个变体 | Ch, Maj |
| 常量方式 | 每轮有固定常量 Tj | 前 64 个质数平方根小数部分 |
| 消息扩展 | Wj 由前 16 字递推,Wj' 额外生成 | Wt 由前 16 字递推 |
| 国家/标准 | 中国 GM/T 0004 | 美国 FIPS 180-4 |
| 典型应用 | 国密证书、电子签章、密码机 | 全球通用、SSL/TLS、区块链 |
你看,轮数虽然相同,但 SM3 在消息扩展阶段多了一个 Wj',而且每轮的布尔函数 FF 和 GG 会在不同轮次切换。这些细节让 SM3 在理论安全性上略高于 SHA-256(比如更好的抗侧信道攻击能力)。不过实际应用中,只要哈希函数没被攻破,两者在安全强度上差别不大。
2.5 避坑与项目经验
hashlib 里 sm3 底层调的是 OpenSSL 的实现,但 OpenSSL 3.0 里 SM3 默认是 EVP_MD 模式,和 GM/T 标准里定义的初始向量有一点点字节序差异。后来我把两边的实现都换成 gmssl 库(国产封装)才对齐。
说到底,做国密开发有三点要盯紧:
- 确认使用的库是否通过商密认证(比如 GmSSL、Trusted Key Management Client)。
- 消息填充方式一定按标准来,不要自己拍脑袋改长度编码的字节序。
- SM3 和 SHA-256 不能混用,混用意味着脱离国密体系,很多合规审查会通不过。
一句话总结:SM3 是国密标准里的 256 位哈希,结构和 SHA-256 相似但细节有差异。选型时优先看产品是否支持 GM/T 0004 认证,而不是只看输出长度。