SpringBoot 国密 SM4 配置加密(自动解密处理器实现)
-
- 前言
- 一、核心依赖
- 二、工具类(ApplicationConfigUtils,Sm4Utils)
- 三、自动解密处理器(Sm4EncryptProcessor)
- [四、Spring 自动注册](#四、Spring 自动注册)
-
- [1. 创建文件](#1. 创建文件)
- [2. 文件内容](#2. 文件内容)
- [五、YML 配置文件(application.yml)](#五、YML 配置文件(application.yml))
- [六、测试 @Value 直接注入明文](#六、测试 @Value 直接注入明文)
- 七、运行结果
- 八、问题解决
- 九、总结
前言
上一篇实现了工具类加解密方法,本篇基于国密 SM4 算法,实现 SpringBoot 环境自动解密处理器,完全贴合 SpringBoot 原生用法,满足等保、密评、国产化合规要求。使用方式:
- 启动自动解密:SpringBoot 启动时自动扫描 ENC(xxx) 并解密;
- 原生注解使用:@Value / @ConfigurationProperties 直接注入明文;
- 无侵入:业务代码无需修改,只加解密组件;
- 国密合规:SM4 对称加密,满足生产环境安全规范。
一、核心依赖
项目依赖 Hutool 国密工具包 + BouncyCastle 加密库:
xml
<!-- Hutool 国密加密(SM4) -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
<version>5.8.20</version>
</dependency>
<!-- BouncyCastle 密码学提供方 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
二、工具类(ApplicationConfigUtils,Sm4Utils)
上一篇博文的工具类,跳转入口如下:
SpringBoot 国密 SM4 配置加密(工具类实现)
三、自动解密处理器(Sm4EncryptProcessor)
java
import com.learn.utils.Sm4Utils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import java.util.HashMap;
import java.util.Map;
/**
* SpringBoot 配置文件自动解密处理器
* 项目启动时会自动解密 ENC(xxx) 格式的配置
*
*/
public class Sm4EncryptProcessor implements EnvironmentPostProcessor {
/**
* 加密标识前缀(和ApplicationConfigUtils保持一致)
*/
private static final String PREFIX = "ENC(";
/**
* 加密标识后缀(和ApplicationConfigUtils保持一致)
*/
private static final String SUFFIX = ")";
/**
* 存放解密后的配置
*/
private final Map<String,Object> decryptMap = new HashMap<>();
/**
* SpringBoot环境初始化时执行,自动解密配置
* @param environment Spring环境对象(存储所有配置)
* @param application SpringBoot应用对象
*/
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 遍历SpringBoot所有配置源
for (PropertySource<?> ps : environment.getPropertySources()) {
// 只处理我们自己写的 application.yml/properties 配置
String name = ps.getName();
if (name.contains("application") && name.contains(".yml") || name.contains(".properties")) {
Object source = ps.getSource();
if (source instanceof Map) {
Map<String, Object> map = (Map<String, Object>) source;
// 遍历所有配置项,识别并解密ENC格式的配置
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object valueObj = entry.getValue();
String value = String.valueOf(valueObj);
// 判断是否是加密格式(ENC(xxx))
if (value.startsWith(PREFIX) && value.endsWith(SUFFIX)) {
// 截取加密串(去掉ENC()标识)
String encryptStr = value.substring(PREFIX.length(), value.length() - SUFFIX.length());
// 调用SM4工具类解密
String decryptStr = Sm4Utils.decrypt(encryptStr);
// 存入解密集合
decryptMap.put(entry.getKey(),decryptStr);
}
}
}
}
}
if(!decryptMap.isEmpty()){
environment.getPropertySources().addFirst(new MapPropertySource("sm4-decrypt-source",decryptMap));
}
}
}
四、Spring 自动注册
注册解密处理器,让SpringBoot启动时识别并执行自动解密逻辑,只需要创建一个文件即可。
1. 创建文件
在 resources/META-INF/ 目录下,创建 spring.factories 文件。
2. 文件内容
注册解密处理器,替换成自己的包路径(核心配置):
java
org.springframework.boot.env.EnvironmentPostProcessor=com.你的包名.Sm4EncryptProcessor

五、YML 配置文件(application.yml)
密钥规则 :SM4 密钥必须是 16 位字符(数字 / 字母均可),生产环境严禁硬编码在配置文件,建议放到 Nacos/Apollo/ 密钥管理系统。加密格式固定:ENC(SM4 加密后的密文)
java
# ====================== 国密 SM4 配置 ======================
sm4:
key: 1234567890123456 # 必须16位,测试使用,生产环境请放配置中心
# ====================== 测试加密配置 ======================
## 单层配置
testPassword: ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)
## 多层配置
test:
password: ENC(1bb11e4cf9eebd2538d53ebcaacb9cfe)
六、测试 @Value 直接注入明文
java
@RestController
public class TestController {
// 直接获取解密后的密码
@Value("${test.password}")
private String testPass;
@Operation(summary = "项目运行后,接口获取已加密的数据")
@GetMapping("test")
public String testSm4(){
System.out.println("@Value方式获取配置信息[多层]:" + testPass);
String property0 = ApplicationConfigUtils.getProperty("sm4.key");
System.out.println("sm4.key数据[多层]:" + property0);
String property1 = ApplicationConfigUtils.getProperty("testPassword");
String property2 = ApplicationConfigUtils.getProperty("test.password");
System.out.println("testPassword数据[单层]:" + property1);
System.out.println("test.password数据[多层]:" + property2);
return property1;
}
}
七、运行结果
java
@Value方式获取配置信息[多层]:123456
sm4.key数据[多层]:1234567890123456
testPassword数据[单层]:123456
test.password数据[多层]:123456
八、问题解决
- 解密不生效 / @Value 拿到的还是密文
解决方案:检查 EnvironmentPostProcessor 文件路径是否正确;检查全类名是否正确;检查配置是否以 ENC( 开头、) 结尾,无空格。 - 密钥非法报错
解决方案:SM4 密钥必须 16 位字符,不能多也不能少。 - 多模块项目找不到配置文件
原因:application.yml文件不存在或路径错误 。解决方案:确保 application.yml 放在 启动模块的 resources 下;或者在pom.xml中配置build。 - 空指针异常
解决方案:检查密文是否正确;检查 Sm4Utils 密钥是否与加密时一致;检查配置项名称是否写错。
九、总结
本篇实现了企业级 SpringBoot 国密 SM4 自动解密方案:
- 启动自动解密,无侵入;
- @Value 直接获取原文;
- 符合等保、密评、国产化要求。