SM4 是我国商用密码标准中的分组密码算法,标准号为 GB/T 32907-2016*(原名 SMS4,最初作为无线局域网标准 WAPI 的配套算法公布)。它的分组长度与密钥长度都是 **128 位(16 字节)**,与 AES-128 的分组长度相同,但算法结构完全不同,*两者的密文互不兼容。
SM4 采用 32 轮非平衡 Feistel 结构,加解密使用同一套轮函数,只是轮密钥顺序相反,因此硬件实现非常紧凑,广泛用于国密 TLS、金融 IC 卡、政务专网等场景。
| 参数 | 可选值 | 说明 |
|---|---|---|
| 密钥长度 | 16 字节(固定) | 128 位,与分组等长 |
| 分组长度 | 16 字节(固定) | 128 位 |
| 模式 | ECB / CBC / CFB / OFB / CTR | 与 AES 的模式语义相同 |
| 填充 | PKCS#7 / ZeroPadding / ANSI X9.23 / NoPadding | 流式模式不使用填充 |
| 向量 IV | 16 字节 | ECB 不使用,其余模式必填 |
可以用下面这组官方向量验证实现是否正确(GB/T 32907-2016 附录 A.1):
0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210681edf34d206965e86b3e94f536e4246把密钥与明文切成 Hex 输入、模式选 ECB、填充选 NoPadding,结果应当与上面的密文完全一致。
OpenSSL 1.1.1 及以上版本内置了 SM4,下面的命令与本工具等价:
openssl enc -sm4-cbc -K 0123456789abcdeffedcba9876543210 -iv 000102030405060708090a0b0c0d0e0f -in plain.txt -out cipher.binopenssl enc -d -sm4-cbc -K 0123456789abcdeffedcba9876543210 -iv 000102030405060708090a0b0c0d0e0f -in cipher.bin -out plain.txt-K 与 -iv 都是 32 位十六进制字符(16 字节)。OpenSSL 默认使用 PKCS#7 填充,与本工具的默认值一致。
页面里的 SM4 是按 GB/T 32907-2016 用 JavaScript 实现的 crypto-js 分组密码插件,复用了 crypto-js 的 ECB / CBC / CFB / OFB / CTR 模式与四种填充,因此使用体验与其他对称加密工具完全一致。S 盒与系统参数取自国标,并已用官方测试向量逐字节校验;加密与解密结果也与 PHP OpenSSL 的 sm4-* 系列算法做过逐字节对照。
这个工具能用于国密改造项目吗?
密文用 Hex 还是 Base64?
NoPadding 模式有什么限制?
为什么解密后末尾多出了一些字符?
SM4 是加密算法还是哈希算法?
SM4 与 AES 相比性能如何?
向量 IV 应该填几位?
支持哪些加密模式与填充?
密钥和明文会被上传到服务器吗?
怎么验证这个工具的实现是正确的?
SM4 和 AES 能互相解密吗?
SM4 的密钥和分组长度是多少?