SpringBoot 国密 SM4 配置加密(自动解密处理器实现)

SpringBoot 国密 SM4 配置加密(自动解密处理器实现)

前言

上一篇实现了工具类加解密方法,本篇基于国密 SM4 算法,实现 SpringBoot 环境自动解密处理器,完全贴合 SpringBoot 原生用法,满足等保、密评、国产化合规要求。使用方式:

  1. 启动自动解密:SpringBoot 启动时自动扫描 ENC(xxx) 并解密;
  2. 原生注解使用:@Value / @ConfigurationProperties 直接注入明文;
  3. 无侵入:业务代码无需修改,只加解密组件;
  4. 国密合规: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

八、问题解决

  1. 解密不生效 / @Value 拿到的还是密文
    解决方案:检查 EnvironmentPostProcessor 文件路径是否正确;检查全类名是否正确;检查配置是否以 ENC( 开头、) 结尾,无空格。
  2. 密钥非法报错
    解决方案:SM4 密钥必须 16 位字符,不能多也不能少。
  3. 多模块项目找不到配置文件
    原因:application.yml文件不存在或路径错误 。解决方案:确保 application.yml 放在 启动模块的 resources 下;或者在pom.xml中配置build。
  4. 空指针异常
    解决方案:检查密文是否正确;检查 Sm4Utils 密钥是否与加密时一致;检查配置项名称是否写错。

九、总结

本篇实现了企业级 SpringBoot 国密 SM4 自动解密方案:

  1. 启动自动解密,无侵入;
  2. @Value 直接获取原文;
  3. 符合等保、密评、国产化要求。
相关推荐
MY_TEUCK9 小时前
【Java 后端】SpringBoot 登录认证与会话跟踪实战(JWT + Filter/Interceptor)
java·开发语言·spring boot
计算机程序定制辅导10 小时前
计算机小程序毕设实战-基于Spring Boot与微信小程序的考研资源共享平台设计与实现基于springboot+微信小程序的考研复习辅助平台【完整源码+LW+部署说明+演示视频,全bao一条龙等】
spring boot·微信小程序·小程序·课程设计
凤山老林15 小时前
从0到1搭建企业级权限管理系统:Spring Boot + JWT + RBAC实战指南
java·spring boot·后端·权限管理·rbac
2401_8788204717 小时前
Sa-Token基础篇
java·spring boot·后端·sa-token
weixin_lizhao19 小时前
50天独立打造企业级API网关(二):安全防护体系与弹性设计
java·spring boot·安全·spring cloud·gateway
Slow菜鸟20 小时前
Docker 学习篇(七)| 实战 — 用 Docker 构建 SpringBoot + Vue 全栈项目
spring boot·学习·docker
普修罗双战士1 天前
项目设计-文章系统发布文章完整前后端设计
java·数据库·vue.js·spring boot·git·intellij-idea
StockTV1 天前
新加坡股票API 实时行情、K 线及指数数据
android·java·spring boot·后端·区块链