使用 Hutool 工具库实现国密 SM4 加密解密
一、环境准备:添加依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version> <!-- 推荐 ≥5.8.x -->
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.70</version> <!-- 提供国密算法支持 -->
</dependency>
注:Bouncy Castle 是 Hutool 实现国密算法的底层依赖,不可省略
二、核心代码实现
- 生成 SM4 密钥
import cn.hutool.crypto.SmUtil;
import cn.hutool.core.util.HexUtil;
// 生成 128 位随机密钥(16 字节)
byte[] keyBytes = SmUtil.sm4().getSecretKey().getEncoded();
String sm4Key = HexUtil.encodeHexStr(keyBytes); // 转为十六进制字符串
System.out.println("SM4 密钥: " + sm4Key); // 示例:6dbfc14984eb7dbe6d4e275429c70a73
- 加密与解密
import cn.hutool.crypto.symmetric.SM4;
public class Sm4Demo {
public static void main(String[] args) {
String content = "需要加密的数据";
String sm4Key = "6dbfc14984eb7dbe6d4e275429c70a73"; // 替换为你的密钥
// 初始化 SM4 实例(默认 ECB 模式)
SM4 sm4 = new SM4(HexUtil.decodeHex(sm4Key));
// 加密 → 十六进制结果
String encrypted = sm4.encryptHex(content);
System.out.println("加密结果: " + encrypted); // 示例:5684c1c131d8dd3f99a3906ba4c9c94f
// 解密 → 原始文本
String decrypted = sm4.decryptStr(encrypted);
System.out.println("解密结果: " + decrypted); // 输出:需要加密的数据
}
}
三、高级用法:自定义加密模式
持 CBC/CTR/CFB 等模式,需指定初始化向量 (IV):
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
// 使用 CBC 模式 + PKCS7 填充
SM4 sm4 = new SM4(
Mode.CBC,
Padding.PKCS7Padding,
HexUtil.decodeHex(sm4Key), // 密钥
"初始向量IV".getBytes() // IV 长度需为 16 字节
);
// 加密(方法同上)
String encrypted = sm4.encryptHex(content);
注意:
> ECB 模式 无需 IV,但安全性较低,推荐 CBC/CTR 模式;
IV 需为 16 字节随机值,且每次加密应不同(可通过 SecureUtil.generateKey(16) 生成)。
四、其他实用技巧
1.密钥管理
避免硬编码:将密钥存储在安全配置中心或环境变量中;
定期轮换:通过 SmUtil.sm4() 生成新密钥并更新系统。
2.数据格式处理
加密结果支持多种输出格式:
sm4.encryptBase64(content); // Base64 编码
sm4.encrypt(content.getBytes()); // 直接返回字节数组
3.算法兼容性
与其他系统交互时,需确认双方使用相同模式+填充方式+IV 生成规则;
Hutool 默认采用 PKCS7Padding(等价于 PKCS5Padding)。
五、技术原理
底层实现:Hutool 通过封装 Bouncy Castle 库支持国密算法,简化了 API 调用;
密钥长度:SM4 为 128 位对称加密,安全性对标 AES-128;
性能建议:批量数据加密时,优先选用 CTR 模式(支持并行计算)
总结
基础流程:
生成密钥 → 初始化 SM4 对象 → 调用 encryptHex()/decryptStr();
安全增强:
务必使用 CBC/CTR 模式 + 随机 IV,避免 ECB 模式;
适用场景:
敏感配置加密、数据库字段保护、跨系统安全通信(需双方约定密钥及参数)。