Skip to content

SM4 在线加密解密工具(国密 SM4)

SM4在线加密解密:解密失败自动排查模式、填充、IV 和编码哪项不对,一键套用;浏览器本地计算,不上传。支持国密 SM4 的 ECB、CBC、CTR、CFB、OFB 模式,PKCS#7(PKCS5Padding)、ZeroPadding、NoPadding 填充,密钥和 IV 可用 Hex、文本或 Base64,附 GB/T 32907 标准测试向量。

无追踪 浏览器中运行 免费
SM4 加解密全程在你的浏览器中完成——输入的密钥和数据不会离开这台设备。
密文
等效的 OpenSSL 命令

需要 OpenSSL 3。命令中包含你输入的密钥。

GB/T 32907-2016 SM4 标准测试向量

由本页同一份引擎在构建时算出,可用来核对你自己的 SM4 实现。
密钥 0123456789abcdeffedcba9876543210
明文 0123456789abcdeffedcba9876543210
密文(加密 1 次) 681edf34d206965e86b3e94f536e4246
密文(连续加密 1,000,000 次) 595298c7c6fd271f0402f804c33d3f66
SM4 引擎已对 GB/T 32907-2016 附录 A 的两个测试向量做了断言,并在 ECB、CBC、CTR、CFB、OFB 五种模式下与 OpenSSL 3 交叉校验。各库默认参数经实跑 OpenSSL、Node.js、sm-crypto、gm-crypt、gmssl 和两个 Go 库,并阅读 Hutool 与 BouncyCastle 源码核实。 — Go Tools 安全团队 · 2026年9月11日

由构建加密工具的开发者撰写并审核。本页引用的每个密文和字节数都由工具引擎实算,并由测试逐项核对。

SM4 速查答案

SM4 密钥长度

16 字节 固定 128 位,即 16 字节:写成 32 位十六进制或 16 个 ASCII 字符。SM4 没有 192 位或 256 位密钥。

GB/T 32907 标准测试向量

681edf34d206965e86b3e94f536e4246 密钥和明文都是 0123456789abcdeffedcba9876543210 时,SM4 加密一次得到 681edf34d206965e86b3e94f536e4246。

SM4 分组长度和轮数

32 轮 分组 16 字节(128 位),加密 32 轮。

CBC 模式下 IV 错了一定会报错吗?

前 16 个字节 不会。只有前 16 个字节解错,最后一个分组里的填充照样校验通过。

什么是 SM4(国密 SM4 分组密码)?

SM4 是中国商用密码标准中的分组密码算法:先以 GM/T 0002-2012 发布,随后成为国家标准 GB/T 32907-2016(2017 年 3 月 1 日起实施),2021 年又通过修正案纳入国际标准 ISO/IEC 18033-3。它是对称密码:加密和解密用同一个 128 位密钥,每次处理 128 位(16 字节)的分组——分组长度与 AES 相同。

在算法内部,每个分组被拆成四个 32 位的字,经过 32 轮迭代。每一轮把其中三个字与轮密钥混合,经过一个 8 位 S 盒和一次线性变换,再并入第四个字。32 个轮密钥由原始密钥和两组固定常数扩展而来;解密与加密是同一套运算,只是轮密钥的顺序倒过来。

分组算法本身一次只能处理正好 16 个字节,所以实际数据总要套一种工作模式。本工具提供五种经典模式:ECB 和 CBC 按整个分组处理,需要填充;CTR、CFB 和 OFB 把 SM4 变成流密码,完全不需要填充。绝大多数「SM4 解密失败」都和 SM4 算法本身无关,而是加解密两端在模式、填充、IV、明文编码或「密钥字符串怎么变成字节」上没有对齐——各个库连单写一个「SM4」指的是哪种模式都不一致。

浏览器内置的 Web Crypto API 不包含 SM4,因此本页自带一份 SM4 实现并在本地运行。它已通过 GB/T 32907 的两个测试向量,并在每种模式下都与 OpenSSL 3 交叉校验过。

// SM4-CBC with PKCS#7 padding using Node.js and its bundled OpenSSL 3.
// Key and IV are both exactly 16 bytes (32 hex digits).
const crypto = require('node:crypto');

const key = Buffer.from('0123456789abcdeffedcba9876543210', 'hex');
const iv = Buffer.from('fedcba98765432100123456789abcdef', 'hex');

const cipher = crypto.createCipheriv('sm4-cbc', key, iv);
const ciphertext = Buffer.concat([cipher.update('hello', 'utf8'), cipher.final()]);
console.log(ciphertext.toString('base64')); // fUQPRg2HAXHGz5ZslzCpSQ==

const decipher = crypto.createDecipheriv('sm4-cbc', key, iv);
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
console.log(plaintext.toString('utf8')); // hello

SM4 在线工具的核心功能

SM4 解密失败自动排查

解密失败时,页面会把密文编码、密钥格式、模式、IV、填充和明文编码逐一重试,直接给出能解出可读文本的那组参数。

常用库的默认参数一键套用

OpenSSL、Hutool、sm-crypto、gm-crypt、tjfoc/gmsm 的默认参数点一下就对齐——这些库连单写「SM4」是 ECB 还是 CBC 都不一致。

五种模式、三种填充,UTF-8 或 GBK

ECB、CBC、CTR、CFB、OFB,搭配 PKCS#7、ZeroPadding 或 NoPadding。明文支持 UTF-8 和 GBK——后者是老 Java 代码在中文 Windows 上的默认编码。暂不支持 GCM。

SM4 密钥和 IV:随机生成,支持 Hex、文本、Base64

一键随机生成 16 字节的密钥或 IV,也可以按代码里的写法填写;实时字节数先确认你手上正好是 16 字节,免得在别处白找原因。

页面上就有 GB/T 32907 标准测试向量

附录 A 的两个结果印在表格里,点一下就能载入,拿来核对任何 SM4 实现是否符合国标。

等效的 OpenSSL 命令

每个结果都附带能复现它的 openssl enc 命令,可以在终端里确认,也方便直接发给同事。

全程在浏览器本地运行

SM4 引擎在本地执行,密钥和数据不会离开页面,断网也能用。

各语言 SM4 库的默认参数对照

OpenSSL 3(openssl enc

-sm4 即 CBC

-sm4-sm4-cbc 的别名。-K-iv 用十六进制,默认 PKCS#7 填充,加 -nopad 才关闭;默认输出原始字节,要 Base64 得加 -base64 -A-K 长度不对时会被截断或补零,只打印一句警告。

Java:Hutool SmUtil.sm4(key)

ECB · PKCS#7

Hutool 只传一个裸的 SM4,由 BouncyCastle 按 ECB + PKCS#7 执行(JCE 里叫 PKCS5Padding)。字符串方法按 UTF-8 编码,encryptHex 输出小写十六进制。要用 CBC 请写 new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv)

Java:BouncyCastle Cipher.getInstance("SM4")

ECB · PKCS#7

需要 IV 的模式没给 IV 时,加密会悄悄生成一个随机 IV,解密则抛出 no IV set when one expected——如果那个随机 IV 没有随密文保存,任何一端都解不开。

JavaScript:sm-crypto

ECB · 十六进制密钥

sm4.encrypt(data, key) 默认 ECB + PKCS#7,密钥要 32 位十六进制字符串,输出小写十六进制。只有 mode: 'cbc' 能切换模式,写其他值会静默按 ECB 处理。sm-crypto-v2 行为相同,但 CBC 不传 iv 时会用全零 IV。

JavaScript:gm-crypt

CBC · 文本密钥 · Base64

默认 CBC,密钥和 IV 都是 16 个字符的 UTF-8 字符串,输出 Base64。字节不是合法 UTF-8 的密钥根本传不进去。

Python:gmssl CryptSM4

PKCS#7 · 密钥只取前 16 字节

模式由调用 crypt_ecb 还是 crypt_cbc 决定。set_key 只读前 16 个字节,更长的密钥会被悄悄截断;用错密钥时通常返回空字节串,而不是报错。

Go:tjfoc/gmsm sm4

默认全零 IV

Sm4Cbc 使用包级 IV,调用 SetIV 之前一直是全零;连 CFB、OFB 也会做 PKCS#7 填充;解填充出错时直接丢弃错误——用错密钥返回 nil,也不报错。

SM4 加密解密示例

GB/T 32907 标准测试向量(ECB,不填充)

密钥 0123456789abcdeffedcba9876543210,明文(Hex)0123456789abcdeffedcba9876543210
681edf34d206965e86b3e94f536e4246

这是 GB/T 32907-2016 附录 A 的示例 1:密钥和明文是同一个 128 位的值,SM4 加密一次得到 681edf34d206965e86b3e94f536e4246。把输出继续加密,累计一百万次得到 595298c7c6fd271f0402f804c33d3f66。两个值都印在本页的测试向量表里,由你正在使用的同一份引擎算出。点 国标测试向量 按钮会载入第一组。

CBC + PKCS#7:中文明文加密成 Base64

密钥 0123456789abcdeffedcba9876543210,IV fedcba98765432100123456789abcdef,明文:国密 SM4 联调测试:订单号 20260911-0042
9VIqdBnH9fiUiytTtZ5AzKLXFKdRvAuzmRI+ep/Yq88rOYRCktyEKHrREAfKKyYtuvG+CaDVjAlp4LvSpqtkaw==

这段明文按 UTF-8 编码是 49 字节,每个汉字占 3 字节。PKCS#7 把它填充到 64 字节,也就是 4 个分组,写成 Base64 是 88 个字符。点 加载示例 会填入完全相同的参数,OpenSSL 面板里给出的命令在终端里能复现同一串 Base64。

CBC 模式 IV 填错:只有开头 16 个字节是乱码

用上面的密文,把 IV 换成 00000000000000000000000000000000 再解密
开头是乱码,后面照常解出「测试:订单号 20260911-0042」

CBC 只把 IV 混进第一个分组,而 PKCS#7 填充在最后一个分组里,所以填充校验照样通过,OpenSSL 不会报任何错。本页会注意到第一个分组解不出可读文本,告诉你密钥和模式是对的、问题出在 IV——或者密文开头 16 个字节本身就是 IV。中文明文里,被切开的那个汉字也会一起显示成乱码。

SM4 在线加密解密怎么用

  1. 1

    选对端库,或者选择模式和填充

    知道对端用的是哪个库,就在「按对端库的默认参数」里直接选它。否则先选「加密」或「解密」,再按对端系统选模式和填充。CTR、CFB、OFB 是流模式,不需要填充,填充下拉框会自动禁用。

  2. 2

    填入密钥和 IV(偏移量)

    两者都必须正好 16 字节。选择这串字符的格式——Hex、文本或 Base64——字节数变绿即表示长度正确。「随机生成」按钮可以生成新的值。

  3. 3

    粘贴要处理的内容

    加密时输入文本(UTF-8 或 GBK)或粘贴十六进制字节;解密(解码)时粘贴密文,并选择它是 Base64 还是 Hex。结果随输入实时更新。

  4. 4

    复制结果,或验证往返

    复制输出,或点「用这段密文去解密」,带着同样的密钥和 IV 切到解密页签验证往返。OpenSSL 面板给出能复现结果的命令。

  5. 5

    SM4 解密失败时看自动排查

    自动排查会列出能让你的输入解出可读文本的参数组合,点一下即可套用。如果只有开头 16 个字节解不出来,提示会指向 IV。

SM4 解密失败的常见原因

把十六进制密钥当成文本读取

32 个字符的十六进制串只有按十六进制解码才是 16 字节。按文本读是 32 字节,SM4 会直接拒绝——遇到会悄悄截断或补齐密钥的代码,就变成了另一个密钥。

✗ 错误
密钥(文本):0123456789abcdeffedcba9876543210  -> 32 字节,被拒绝
✓ 正确
密钥(Hex): 0123456789abcdeffedcba9876543210  -> 16 字节

CBC 加密的密文用 ECB 解密

加解密两端必须用同一种模式。CBC 密文按 ECB 解密,每个分组都是乱码,而且通常在最后的填充校验上失败。

✗ 错误
加密:SM4/CBC/PKCS5Padding
解密:SM4/ECB/PKCS5Padding  -> 解密失败(bad decrypt)
✓ 正确
加密:SM4/CBC/PKCS5Padding
解密:SM4/CBC/PKCS5Padding,IV 相同

解密用的 IV 和加密时不同

CBC 模式下 IV 填错不会报错:开头 16 个字节是乱码,其余部分正常解出。如果只有明文开头坏了,先核对两边的 IV。

✗ 错误
解密 IV 00000000000000000000000000000000
-> 开头乱码 + 「测试:订单号 20260911-0042」
✓ 正确
解密 IV fedcba98765432100123456789abcdef
-> 「国密 SM4 联调测试:订单号 20260911-0042」

把 Base64 密文当成十六进制

Base64 和十六进制是同一串字节的两种写法。按错误的格式读取,从一开始交给算法的就是错误的输入。

✗ 错误
9VIqdBnH9fiUiytTtZ5AzKLXFKdRvAuzmRI+ep/Yq88rOYRCktyEKHrREAfKKyYtuvG+CaDVjAlp4LvSpqtkaw==  按 Hex 读 -> 不是合法的十六进制
✓ 正确
9VIqdBnH9fiUiytTtZ5AzKLXFKdRvAuzmRI+ep/Yq88rOYRCktyEKHrREAfKKyYtuvG+CaDVjAlp4LvSpqtkaw==  按 Base64 读 -> 64 字节

ZeroPadding 吞掉了数据末尾真正的零字节

ZeroPadding 分不清哪些零是填充、哪些是数据,明文如果本来就以 0x00 结尾,这些字节会丢失。不是纯文本的数据请用 PKCS#7。

✗ 错误
ZeroPadding:61 62 00  -> 解密得到 61 62
✓ 正确
PKCS#7:     61 62 00  -> 解密得到 61 62 00

以为「SM4」在哪儿都是同一种模式

OpenSSL 把 sm4 当作 CBC;BouncyCastle——也就是 Hutool SmUtil.sm4(key) 的底层——把 SM4 当作 ECB + PKCS#7。两个系统都说「就用 SM4」,模式却可能不一样。

✗ 错误
Java:   Cipher.getInstance("SM4")  -> ECB + PKCS#7
OpenSSL:openssl enc -sm4           -> CBC
✓ 正确
Java:   Cipher.getInstance("SM4/CBC/PKCS5Padding")
OpenSSL:openssl enc -sm4-cbc

一端按 GBK、另一端按 UTF-8 编码明文

Java 的 getBytes() 不指定字符集时使用平台默认编码,JDK 17 及以前在中文 Windows 上就是 GBK。同一段中文因此加密出不同的密文,另一端解出来就是乱码。

✗ 错误
"国密SM4 test".getBytes()  // 中文 Windows、JDK <= 17:GBK
-> ECB 密文 3188d06cf28db70092f8753cbd5ee518
✓ 正确
"国密SM4 test".getBytes(StandardCharsets.UTF_8)
-> ECB 密文 d830308b0ae4fa7b9a2b5d59f7f65ca5

什么时候需要 SM4 在线加解密

对齐前后端的 SM4 加密结果
Java 服务端和前端对同一段文本加密出的密文不一样。在这里按两边各自的库预设分别复现,一眼看出是哪个参数不同。
排查对接方发来的密文解不开
合作方发来的 SM4 密文按约定的密钥和 IV 解不开。把它粘进来,让自动排查找出对方实际用的模式、填充或编码。
验证 SM4 实现是否符合国标
先用本页的 GB/T 32907 测试向量跑一遍你的代码,再比对一次 CBC 往返,确认无误后再碰生产数据。
为国密改造准备测试数据
系统从 AES 迁移到 SM4 时,在这里生成已知的密钥、IV、密文三元组,作为新测试用例的固定数据。
直观理解分组密码的工作模式
用 ECB 和 CBC 分别加密两个相同的分组,或者故意用错 IV 解密,观察密文和输出分别怎么变。

SM4 算法与工作模式详解

SM4 的分组长度、密钥长度与轮数
SM4 以 128 位密钥加密 128 位分组,共 32 轮。每一轮对一个 32 位字做 8 位 S 盒替换,再做一次线性变换:把这个字与它自身的四个循环移位结果异或。解密执行同样的 32 轮,轮密钥顺序相反。
ECB:每个分组各自加密
ECB 对每个 16 字节分组独立加密,不需要 IV,但相同的明文分组会得到相同的密文分组,数据的规律依然可见。输入不是 16 字节整数倍时需要填充。
CBC:分组链接与 IV(偏移量)
CBC 在加密前把每个明文分组与前一个密文分组异或,第一个分组则与 IV 异或。由于 IV 只参与第一个分组,IV 错误时只会让明文的前 16 个字节出错,最后一个分组里的填充不受影响,因此往往根本不报错。
CTR、CFB、OFB:把 SM4 当流密码用
这三种模式加密的是计数器或反馈值,再与数据异或,所以密文与明文等长,也不需要填充。CTR 把整个 16 字节 IV 当作一个 128 位大端计数器递增,与 OpenSSL 一致。IV 错误时,CTR 和 OFB 整段乱码,CFB 只有第一个分组出错。
三种填充规则
PKCS#7 追加 1 到 16 个值为 n 的字节,即使数据正好是整数个分组也要再补一整个分组。ZeroPadding 只在需要时补 0x00,解密时去掉末尾所有零字节。NoPadding 不改动数据,拒绝不满整数个分组的输入。

SM4 加密的正确用法

新设计不要选 ECB
ECB 会泄露哪些分组内容相同。除非要对接一个已经在用 ECB 的系统,否则选 CBC 或 CTR。
每条消息使用新的随机 IV
IV(偏移量)不需要保密,但同一密钥下不能重复。每条消息随机生成,并与密文一起存储或传输。
给密文加上完整性校验
国家标准 GB/T 17964-2021《分组密码算法的工作模式》写明,它描述的工作模式只保护机密性,不保护完整性。CBC 模式下改动 IV 的一个字节,就能把 pay=100.00 变成 pay=900.00,解密照样成功。对 IV 和密文计算 MAC,解密前先校验,例如用 HMAC 生成器
把每个参数都写进接口文档
「用 SM4 加密」不算规范。要写清模式、填充、密钥和 IV 的编码方式、明文字符集,以及密文是十六进制还是 Base64。
真实密钥不要进网页,也不要进代码
本页只用测试密钥。生产密钥应放在密钥管理系统或密码机里,运行时加载,而不是粘贴到网页或提交进代码仓库。

SM4 加密解密常见问题

SM4 解密失败或报异常(填充错误、乱码)怎么办?
SM4 解密要成功,必须和加密方完全一致:密钥字节、模式、IV(偏移量)、填充,以及密文是按十六进制还是 Base64 写出来的。你看到的报错——「bad decrypt」、填充异常或一屏乱码——并不告诉你是哪一项不对,有些库甚至不报错、直接返回空结果。照样把密文、密钥和 IV 粘进来:解密失败时,本页会把密文编码、密钥格式、模式、IV 和填充的所有组合逐一重试——包括被库悄悄截成 16 字节的密钥和 GBK 编码的明文——列出能解出可读文本的那几组,并标出哪些通过了 PKCS#7 填充校验。如果只有开头 16 个字节是乱码,说明密钥和模式是对的,IV 不对。
SM4 密钥长度是多少?可以用 256 位密钥吗?
SM4 密钥固定 128 位,也就是 16 字节,和分组长度相同。GB/T 32907 只定义了 128 位这一种密钥长度,没有 192 位或 256 位的 SM4。如果对方要求 256 位密钥,先确认是不是把 32 位十六进制字符串当成了 32 个字符、按每个字符 8 位(32×8=256)算的。16 个字节可以写成 32 位十六进制,也可以是 16 个 ASCII 字符,两者搞混是最常见的密钥错误:0123456789abcdeffedcba9876543210 按十六进制读是 16 字节,按文本读却是 32 字节,会被直接拒绝。密钥框旁边的格式下拉框和字节数就是为此设计的。
SM4 的 IV(偏移量)是什么?长度必须是多少?
IV(初始化向量,国内文档常叫偏移量)是 CBC、CTR、CFB、OFB 模式处理第一个分组时混入的 16 字节值,ECB 不用 IV。它必须正好 16 字节:写成 32 位十六进制,或 16 个 ASCII 字符;如果报 IV 长度不对,先检查是不是把 32 位十六进制当成文本读成了 32 字节。IV 不需要保密,但同一个密钥下不能重复,通常随机生成后放在密文开头或随密文一起传。CBC 模式下 IV 错了往往不报错,只有解出来的前 16 个字节是乱码。另外,有的库在没传 IV 时会悄悄用全零 IV(如 sm-crypto-v2、Go 的 tjfoc/gmsm),而 Java 的 BouncyCastle 会自动生成一个随机 IV——这个 IV 如果没随密文保存,谁都解不开。
SM4 的 ECB 和 CBC 模式有什么区别?该用哪个?
用 CBC(或 CTR),并且每条消息都用新的随机 IV。ECB 会把相同的 16 字节明文分组加密成相同的密文分组,数据里重复的结构会直接暴露在密文上。只有对接一个已经在用 ECB 的系统时才选 ECB。另外,这两种模式都不能发现篡改:如果这一点重要,还要对 IV 和密文计算一个 MAC 一起发送,例如用 HMAC 生成器
SM4 填充方式怎么选:PKCS5Padding、PKCS7、ZeroPadding、NoPadding 有什么区别?
PKCS#7 总是追加 1 到 16 个字节,每个字节的值都等于追加的字节数,接收方可以毫无歧义地去掉它。对 SM4 这种 16 字节分组的算法,Java 里的 PKCS5Padding 就是同一种填充——BouncyCastle 把这两个名字接到同一段代码上。ZeroPadding 只在不足一个分组时补 0x00;解密时 Hutool 和 BouncyCastle 会去掉末尾所有的 0x00,连数据里真正的零字节也一起去掉,而 Python 的 gmssl 只去掉一个。NoPadding 要求输入正好是 16 字节的整数倍。CTR、CFB、OFB 是流模式,从不填充。解密结果末尾多出空格、方框或换行,通常是填充没有去掉:PKCS#7 填充的数据按 NoPadding 解密,末尾会留下 n 个值为 n 的字节(0x09、0x0A、0x0D 会显示成制表符和换行);把输出切到 Hex,看最后一组就能认出来。
SM4 加密后密文有多长?能从密文看出用的是什么模式吗?
按字节算。ECB 和 CBC 用 PKCS#7 填充时,密文长度是明文长度向上补到 16 的整数倍;明文正好是 16 的整数倍时还要再多一整组。所以 5 字节和 15 字节的明文都得到 16 字节,16 字节的明文得到 32 字节。ZeroPadding 只补到下一个 16 的整数倍,NoPadding 不改变长度;CTR、CFB、OFB 的密文与明文等长。写成十六进制时,字符数是字节数的 2 倍;写成 Base64 是 4×⌈字节数/3⌉ 个字符:16 字节是 24 个,32 字节是 44 个,64 字节是 88 个。如果把 IV 放在密文开头,还要再加 16 字节。单看密文判断不了模式,但有两条线索:长度不是 16 的整数倍,基本可以排除带填充的 ECB/CBC;密文里有两段完全相同的 16 字节,多半是 ECB。拿不准时,把密文粘进解密页签,自动排查会把各种模式都试一遍。
SM4 每次加密结果都一样吗?为什么和别的工具算的不同?
ECB,以及 IV 固定的 CBC、CTR、CFB、OFB,在密钥和明文不变时每次结果都相同;每次随机生成 IV 时,结果每次都不同,这是正常的。除此之外,逐项核对模式、填充、密钥是按十六进制还是文本读的、明文用什么编码——大多数代码是 UTF-8,但老 Java 代码在中文 Windows 上调用 getBytes() 得到的是 GBK——以及结果怎么输出:Base64、小写十六进制还是大写十六进制。参数完全一致、IV 固定时,两个正确的实现输出必然相同。如果怀疑其中一个工具有问题,先用 GB/T 32907 标准测试向量把两边都验一遍。
怎么验证自己写的 SM4 实现是否正确?
先用 GB/T 32907-2016 附录 A 的两个测试向量。密钥和明文都是 0123456789abcdeffedcba9876543210 时,加密一次必须得到 681edf34d206965e86b3e94f536e4246,连续加密一百万次得到 595298c7c6fd271f0402f804c33d3f66。这两个向量只检验分组算法本身,所以接着再用固定的密钥和 IV 以 CBC 模式加密一段文本,和本页或本页给出的 OpenSSL 命令对比。本页背后的引擎已经对这两个向量做了断言,并在五种模式下与 OpenSSL 3 交叉校验。
OpenSSL 能做 SM4 加密解密吗?
能。OpenSSL 3 自带 SM4 的 ECB、CBC、CFB、OFB 和 CTR 模式。用法是 openssl enc -sm4-cbc -K <32 位十六进制> -iv <32 位十六进制>-K 直接接收十六进制的原始密钥,不经过口令派生;-nopad 关闭 PKCS#7 填充;-base64 -A 读写单行 Base64。有两处要当心:只写 -sm4 就是 CBC;-K 长度不对时会被截断或补零,只打印一句警告。本页的 OpenSSL 面板会按当前参数生成命令;openssl enc 不支持 ZeroPadding,这时面板会直接说明,而不是给出一条对不上的命令。
Java(Hutool)或 JavaScript(sm-crypto)加密的 SM4 密文怎么解密?
先确认对方实际用的模式和填充——很多代码里根本没写。Hutool 的 SmUtil.sm4(key) 只传算法名 SM4,由 BouncyCastle 补成 ECB + PKCS#7(Java 里叫 PKCS5Padding);只有写成 SM4/CBC/PKCS5Padding 这样的完整算法串才是 CBC。JavaScript 的 sm-crypto 默认也是 ECB,密钥是 32 位十六进制字符串,密文输出小写十六进制;gm-crypt 默认 CBC,密钥是 16 个字符的文本,输出 Base64。再确认明文字符集:Hutool 的字符串接口固定用 UTF-8,而直接调用 getBytes() 在 JDK 17 及更早的中文 Windows 上可能是 GBK,密文会不同。在 按对端库的默认参数 里选中对应的库可以一键对齐,也可以手动填写;有一项拿不准,照样把密文粘进来,自动排查会把模式、填充、IV 和编码的组合试一遍。
SM4 安全吗?在线加解密会上传数据吗?
就算法本身而言,SM4 使用 128 位密钥、32 轮迭代;RFC 8998(2021)写明,截至成文时 SM4 没有已知的弱密钥,也未发现安全问题。实际风险几乎都来自用法:ECB 会暴露数据规律,CBC 等模式不能发现篡改。至于本页,数据不会上传。浏览器本身不带 SM4,本页自带一份 SM4 实现并在本地运行;你可以打开开发者工具的「网络」面板,确认没有任何请求发出,或者干脆断网,工具照常可用。所以它适合处理测试数据、调试联调问题和学习。但这并不意味着网页是存放生产密钥的地方:生产密钥应该放在密钥管理系统或密码机里,而不是任何网站的输入框。
SM4 和 AES 有什么区别?
两者都是 128 位分组的分组密码,模式和填充的用法完全一样——这也是 SM4 的联调问题看起来和 AES 一模一样的原因。SM4 加密 32 轮,只有 128 位一种密钥长度;AES-128 是 10 轮,AES 还有 192 位和 256 位密钥。SM4 是中国国家标准 GB/T 32907-2016,2021 年起也和 AES 一起列入国际标准 ISO/IEC 18033-3,用于要求使用国产商用密码的场景;AES 是美国 NIST 的标准 FIPS 197。需要 AES 加密请用 AES 在线加密工具

AES 解密工具 — 兼容 OpenSSL 与 CryptoJS

安全工具

在线解密 AES —— 支持 GCM/CBC/CTR、口令或原始密钥,自动识别 OpenSSL 与 CryptoJS 的 "U2FsdGVkX1" 格式。100% 浏览器本地运行,密钥永不离开页面。

AES 加密工具 — GCM、CBC 与 CTR 模式

安全工具

免费在线 AES 加密工具 — 支持 AES-128/192/256、GCM/CBC/CTR 模式,可用口令(PBKDF2)或原始密钥。100% 浏览器本地运行,不上传任何数据。

Bcrypt 哈希生成器与验证器

安全工具

在线生成并验证 bcrypt 密码哈希——可调成本因子,支持 $2b$/$2a$/$2y$ 前缀。100% 在浏览器中运行,密码绝不上传。

CRC校验计算器(循环冗余校验)

安全工具

CRC校验在线计算:粘贴十六进制或文本,一次算出 CRC-8/16/32 共 63 个变体,含 CRC16 Modbus。设备返回的值对不上时填进反查框,直接告诉你是哪个变体——MODBUS、CCITT-FALSE、XMODEM、KERMIT。全程浏览器本地计算。

HMAC 生成器与签名校验工具

安全工具

免费在线 HMAC 生成与校验工具。支持文本、Hex 或 Base64 密钥计算 HMAC-SHA256/SHA1/SHA384/SHA512,输出 Hex/Base64/Base64URL。100% 在浏览器中运行 —— 密钥永不离开页面。

JWT 解码器 · 在线解码工具

安全工具

免费 JWT 解码器,在线即时解码 JWT 令牌。查看头部、载荷、签名以及过期时间、算法和声明详情。100% 浏览器本地运行——令牌绝不离开你的设备。无需注册、无跟踪。