配置文件的安全管理是企业级应用等保合规、数据安全的核心环节。 此前我们学习的配置引用、多环境管理等均为 SpringBoot 原生能力;而敏感配置加密并非框架自带功能,却是生产环境必备能力
配置文件中明文存储敏感数据是高危安全漏洞:
数据库账号密码泄露 → 数据被窃取 / 篡改
第三方服务密钥泄露 → 资产损失
生产环境配置提交到 Git → 永久泄露无法挽回
企业级规范:所有敏感配置必须加密存储,解密密钥(盐值)绝不硬编码在配置文件中。
我们先编写明文配置,并通过单元测试读取配置,作为基准测试。
src/main/resources/application.yml
# 明文敏感配置(生产环境禁止使用)
datasource:
username: root
password: 123456SpringBoot 3 完全弃用 JUnit 4,必须使用 JUnit 5 (Jupiter) 编写测试:
package com.lusifer.boot;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class PropertiesTest {
// 读取明文配置
@Value("${datasource.password}")
private String password;
@Test
public void testReadPlainText() {
log.info("明文密码:{}", password);
}
}执行测试,控制台输出:
明文密码:123456Jasypt 是 Java 生态最主流的配置加密库,3.0.6 版本正式适配 Spring Boot 3
引入依赖
修改 pom.xml,引入 starter 启动器 和 加密插件:
<dependencies>
<!-- SpringBoot 3 Web依赖(基础依赖) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Jasypt 适配 SpringBoot 3 核心依赖 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- SpringBoot 3 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Jasypt Maven加密插件(批量加密配置) -->
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.6</version>
</plugin>
</plugins>
</build>Jasypt 提供标准语法:
DEC(明文):待加密的内容
ENC(密文):已加密的内容(框架自动解密)
# 用 DEC() 包裹需要加密的敏感信息
datasource:
username: root
password: DEC(123456)盐值是解密的核心密钥,必须自定义、复杂度高、绝不泄露。 示例盐值:Sb3#Jasypt@2026!Secure(生产环境请自行生成随机字符串)
必须在终端执行,不要在 IDEA 直接运行
mvn jasypt:encrypt -Djasypt.encryptor.password=Sb3#Jasypt@2026!Secure执行成功后,配置文件会自动替换:
datasource:
username: root
password: ENC(5smCk9sZJkL9X2bP8aQ7rT4yU1iO3pS5dF8gH0jK2lZ4xV6bN8mQ0wE2rT1yU3)在 application.yml 中添加 Jasypt 配置,适配 SpringBoot 3 + JDK17:
# Jasypt 加密配置(SpringBoot 3 兼容版)
jasypt:
encryptor:
# 加密算法(JDK17默认支持,高安全性)
algorithm: PBEWITHHMACSHA512ANDAES_256
# 随机向量生成器(解决SB3兼容问题,必加)
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
# 密文标识前缀/后缀
property:
prefix: ENC(
suffix: )
# 加密后的敏感配置
datasource:
username: root
password: ENC(5smCk9sZJkL9X2bP8aQ7rT4yU1iO3pS5dF8gH0jK2lZ4xV6bN8mQ0wE2rT1yU3)优先级从高到低
# Jar 包启动时传入盐值
java -jar app.jar --jasypt.encryptor.password=Sb3#Jasypt@2026!Secure# Linux/Mac
export JASYPT_ENCRYPTOR_PASSWORD=Sb3#Jasypt@2026!Secure
# Windows
set JASYPT_ENCRYPTOR_PASSWORD=Sb3#Jasypt@2026!SecureNacos/Apollo
将盐值托管在配置中心,配置文件不存储任何密钥信息。
除了 Maven 插件,我们可以编写工具类手动加密,方便开发调试:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.iv.RandomIvGenerator;
public class JasyptUtils {
// 盐值
private static final String SALT = "Sb3#Jasypt@2026!Secure";
/**
* 加密
*/
public static String encrypt(String plainText) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
encryptor.setPassword(SALT);
encryptor.setIvGenerator(new RandomIvGenerator());
return encryptor.encrypt(plainText);
}
/**
* 解密
*/
public static String decrypt(String cipherText) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
encryptor.setPassword(SALT);
encryptor.setIvGenerator(new RandomIvGenerator());
return encryptor.decrypt(cipherText);
}
public static void main(String[] args) {
System.out.println("加密后:" + encrypt("123456"));
System.out.println("解密后:" + decrypt("加密后的密文"));
}
}直接运行之前的 JUnit 5 测试类,无需修改代码:
@Slf4j
@SpringBootTest
public class PropertiesTest {
@Value("${datasource.password}")
private String password;
@Test
public void testReadEncryptedText() {
// Jasypt自动解密密文
log.info("解密后密码:{}", password);
}
}测试结果
解密后密码:123456证明密文已被框架自动解密,业务代码无任何侵入!