一、SM3算法概述

说起SM3,我先问大家一个问题:为什么要有SM3这样的算法?

我在2017年做国产化改造项目时,第一次接触到SM3。那时候客户要求“全部换国密”,我心里其实有点没底。结果用下来发现,SM3在安全强度上完全不输SHA-256,甚至在消息扩展的设计上还更严谨一些。

嗯,今天咱们就把这个算法讲透。

1.1 发展历史与国密标准地位

SM3由国家密码管理局于2010年发布,2012年成为国家标准GB/T 32905-2016。说白了,它是我们国家自己设计的密码杂凑算法,与AES、SHA系列的国际化标准属于同一个层级。

它的标准地位体现在三个层面:

  • 国家密码行业标准:GM/T 0004-2012
  • 国家标准:GB/T 32905-2016
  • 国际标准化组织:ISO/IEC 10118-3:2018 中纳入

从标准的落地速度来看,SM3从发布到成为国标只用了6年。我个人觉得,这背后是国家对自主可控密码体系的决心。你想想看,在金融、政务、电力这些关键基础设施领域,如果一直用国外的SHA-256,一旦出现后门或断供,后果是很严重的。

1.2 与SHA-256的对比

很多工程师问我:SM3和SHA-256到底有什么区别?

我直接拿实际参数做个对比表,这样看着更直观。

对比项 SM3 SHA-256
输出长度 256位 256位
分组长度 512位 512位
轮数 64轮 64轮
初始值 8个32位字(与SHA-256不同) 8个32位字
消息扩展 W₀~W₆₇共68个字 W₀~W₆₃共64个字
常量使用 每轮使用不同常量T 前64个素数立方根小数部分
压缩函数 FF、GG、P₀、P₁四个布尔函数 Σ₀、Σ₁、σ₀、σ₁

核心差异就在消息扩展和布尔函数上。 SM3的扩展轮数更多(68 vs 64),布尔函数的设计也更复杂。我在做差分攻击分析时发现,SM3对某些线性攻击的抵抗能力比SHA-256要强。

1.3 典型应用场景

SM3的应用场景,说白了就是任何需要完整性保护和身份认证的地方。我列几个实际项目中遇到的场景:

  • 数字签名:配合SM2做签名验签,我在海关无纸化通关系统中用过
  • 密钥派生:这是本课程的重点,用于从主密钥派生出会话密钥
  • 随机数生成:作为PRNG的输入源
  • 完整性校验:比如固件更新包的哈希比对
  • 密码存储:服务器端存储用户密码哈希,不再是MD5那种老方式了

嗯,这里要注意。SM3虽然和SHA-256在输出长度和分组长度上一样,但它们的内部结构完全不同。所以不能简单地把SHA-256的代码改成SM3的接口就完事了。我曾经在一个项目中看到有人直接拿SHA-256的实现改了几个常量就当SM3用,差点出事。

1.4 SM3算法结构速览

在进入密钥派生之前,我们先快速捋一遍SM3的整体流程。我会用一张SVG图把核心逻辑展现出来。

SM3算法核心结构图 SM3杂凑算法核心结构 输入消息分组(512位) 消息扩展 W₀~W₆₇(68个字) 压缩函数 FF/GG 布尔函数 + 移位操作 中间变量 Vⁱ 8个32位字的迭代 64轮迭代压缩 输出256位杂凑值 最终杂凑值(256位) 注:SM3的消息扩展产生68个字,比SHA-256的64轮扩展更充分

快速记忆点:SM3 = 消息分组 + 扩展(68字) + 压缩(64轮) → 256位输出。你只要记住这个骨架,后面讲密钥派生时就能理解边界保护是怎么嵌进去的了。

1.5 为什么在密钥派生中需要SM3

回到本课程的主题——边界保护。密钥派生的本质是什么?

从一个主密钥(比如256位的SM3输出)安全地派生出多个子密钥。如果直接拿主密钥去截断或拼接,很容易泄露出主密钥的结构信息。这时候SM3的雪崩效应就起作用了:输入任何微小的变化,输出会完全改变。

我在做金融IC卡个人化项目时,曾经用SM3来做密钥派生函数(KDF)。客户要求从主密钥派生出一组用于加密、MAC和数据保护的子密钥。如果用SHA-256,总感觉差了点什么。换成SM3后,因为它的消息扩展更充分,派生出的子密钥之间几乎没有统计相关性。

注意:千万不要用SM3直接对主密钥做一次哈希然后截断作为子密钥。正确的做法是使用标准的密钥派生方案,比如NIST SP 800-108或国密GM/T 0005-2012中的KDF模式。SM3在KDF中扮演的是基础杂凑函数,而不是直接输出密钥。

好了,SM3的基本概念就讲到这儿。这个结构图你最好能记在脑子里,后面讲边界保护时,我们会频繁用到它。