SM4 加密 / 解密

用 SM4 加密或解密 —— GB/T 32907-2016,中国国家 128 位分组密码 —— 提供 ECB 与 CBC 两种模式、PKCS#7 填充。输出与 openssl enc -sm4-ecb / -sm4-cbc 逐字节兼容。全部在浏览器中运行;不会上传任何数据。
始终应用 PKCS#7 填充,与 OpenSSL enc 完全一致。
按以下方式读取输入:
按以下方式输出:
OpenSSL 交叉验证 —— 在这里加密,然后运行 openssl enc -d -sm4-cbc -K <hexkey> -iv <hexiv> -in file.sm4 -out file.txt(或去掉 -iv 用 -sm4-ecb):字节完全一致,因为本页使用的 PKCS#7 填充与 OpenSSL 相同。
自检
重放 GB/T 32907-2016 附录 A.1 已知答案向量、由独立 Python 参考实现产出的六个确定性 ECB/CBC 交叉向量、全部四个示例池,以及反向路径(错误密钥长度、非分组整数倍的密文、被篡改的填充都必须被拒绝)。
什么是 SM4?
一句话:SM4 是中国国家标准的分组密码 —— 128 位分组、128 位密钥、32 轮非平衡 Feistel 结构,发布为 GB/T 32907-2016(前身 GM/T 0002-2012),在中国“SM”套件中扮演的角色正如 AES 在 NIST 世界里的角色。
SM4 与 AES 一览
方面SM4AES
分组大小128 位128 位
密钥长度仅 128 位128 / 192 / 256 位
轮数3210 / 12 / 14
结构非平衡 Feistel(每轮更新一个 32 位字)代换–置换网络(每轮作用于整个状态)
S 盒一个 8×8 盒,每轮用 4 次一个 8×8 盒,每轮用 16 次 + MixColumns
标准模式ECB、CBC(本页);TLS 套件中的 GCM/CTR(RFC 8998)ECB、CBC、CTR、GCM……
发布时间2012 年(GM/T 0002-2012;GB/T 32907-2016);已纳入 ISO/IEC 18033-3:20102001 年(FIPS 197)

同一份工作,不同的设计:两者都是带公开 8×8 S 盒的 128 位分组密码,但 SM4 迭代 32 轮轻量 Feistel,而 AES 施加 10–14 轮更重的整状态变换。软件实现中 AES 通常更快(得益于 AES-NI 硬件指令);SM4 则在中国平台的专用 CPU 扩展上达到相当水准。两者都没有可行的攻击;128 位密钥就是 128 位密钥。

为什么用 SM4 而不是 AES?

为了合规与互操作,而不是强度:中国商用密码法规要求受认证行业使用 SM 套件,TLCP 及带 RFC 8998 套件的 TLS 1.3 等协议会协商 SM4。如果你的对手方、监管机构或硬件只认 SM4,那就用 SM4。如果可以自由选择,本站 AES 页面的 AES-256 仍是全球默认。

常见错误
  • 对结构化数据用 ECB。相同明文分组产生相同密文分组 —— 经典的企鹅图。数据超过一个分组时,请用 CBC(本页默认)并配新鲜的 IV。
  • 密钥必须恰好 16 字节。与 AES 不同,SM4 没有 192/256 位变体。“password”这类口令不是密钥 —— 请先用 KDF 派生(参见口令哈希生成器)。
  • 以为填充是可选的。本页与 OpenSSL enc 一样总是应用 PKCS#7,因此 16 字节明文会加密成 32 字节。刻意不提供无填充的裸 SM4。
  • 在 CBC 中复用 IV。CBC 中重复的密钥+IV 组合会泄露消息前缀的相等性。每条消息生成随机 IV,并把它与密文一起传送。
常见问题

和 OpenSSL 兼容吗?兼容 —— 逐字节一致。openssl enc -sm4-cbc -K 0011... -iv 4455... -in in.txt -out out.sm4(OpenSSL 1.1.1+)对相同密钥、IV 和输入产出的密文与本页打印的完全相同;GmSSL 亦然。

为什么这里没有 SM4-GCM?标准周边的库生态主要在 TLS 栈内暴露 SM4-GCM;本页对齐的面向文件的命令行约定(enc)只覆盖 ECB/CBC。带认证的 SM4 属于协议层的事。

WebCrypto 里有 SM4 吗?没有 —— 没有任何浏览器实现它。所以本页用 JavaScript 从零实现,并把标准自带的测试向量接进了上面的自检。

能解密别处加密的内容吗?能 —— 只要知道模式、密钥、IV,并且确认用了 PKCS#7:把密文按 hex 或 Base64 粘贴,切到“解密”即可。