1. 概述
jasypt-spring-boot 是 Jasypt(Java Simplified Encryption)加密框架与 Spring Boot 的集成组件,用于对 Spring Boot 应用配置文件中的敏感信息(如数据库密码、API 密钥、Token 等)进行加密保护,防止敏感信息以明文形式出现在配置文件中。
该组件通过自动配置机制,在应用启动时自动识别并解密配置文件中使用 ENC(...) 包裹的加密属性,使开发者无需修改业务代码即可实现配置加密。
1.1 核心特性
-
零侵入集成:通过 Starter 自动配置,无需修改业务代码
-
多种加密算法支持:支持 PBE、AES 等多种对称加密算法
-
灵活的密钥提供方式:支持配置文件、环境变量、JVM 参数、系统属性等多种密钥注入方式
-
自定义加密器:支持实现 StringEncryptor 接口自定义加密逻辑
-
全环境覆盖:支持 application.properties/application.yml/ 系统属性 / 环境变量等所有 Spring Environment 配置源
2. 快速开始
2.1 引入依赖
在项目的 pom.xml(Maven)或 build.gradle(Gradle)中添加 jasypt-spring-boot-starter 依赖。该 Starter 已内置兼容的 jasypt-core,无需单独引入原生 Jasypt 库。
Maven
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
Gradle
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5")
版本选择建议: Spring Boot 2.4.x ~ 2.7.x 推荐使用 3.0.5+;Spring Boot 3.0.x ~ 3.5.x 推荐使用 3.0.5 或 4.0.4;Spring Boot 3.2+ 存在兼容性问题时建议升级到 4.0.4。
2.2 配置加密密钥
Jasypt 需要一个密钥(password)来执行加密和解密操作。以下是几种常见的密钥配置方式,按安全性从低到高排列:
方式一:配置文件中指定(开发环境)
在 application.yml 中直接配置密钥,仅适用于开发和测试环境。
jasypt:
encryptor:
password: "your-secret-key" # 加密/解密密钥
方式二:JVM 启动参数(推荐生产环境)
通过 JVM 参数传递密钥,避免密钥出现在配置文件中。
java -jar your-app.jar -Djasypt.encryptor.password=your-secret-key
方式三:环境变量(推荐生产环境)
通过系统环境变量传递密钥,这是生产环境最常用的方式。
# Linux / macOS
export JASYPT_ENCRYPTOR_PASSWORD=your-secret-key
java -jar your-app.jar
# Windows
set JASYPT_ENCRYPTOR_PASSWORD=your-secret-key
方式四:配置文件引用环境变量
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD:default-dev-key}
2.3 生成加密密文
在使用加密配置之前,需要先生成敏感信息的密文。以下是几种常用的密文生成方式:
方式一:命令行工具
下载 Jasypt 官方命令行工具,解压后进入 bin 目录执行加密命令:
# Linux / macOS
./encrypt.sh input="root123" password="your-secret-key" algorithm=PBEWithMD5AndDES
# Windows
encrypt.bat input="root123" password="your-secret-key" algorithm=PBEWithMD5AndDES
参数说明:
-
input:要加密的明文 -
password:加密密钥(需与项目中配置的一致) -
algorithm:加密算法(需与项目中配置的一致)
方式二:Java 代码生成
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
public class EncryptUtil {
public static void main(String[] args) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("your-secret-key");
encryptor.setAlgorithm("PBEWithMD5AndDES");
String plainText = "root123";
String encrypted = encryptor.encrypt(plainText);
System.out.println("密文: " + encrypted);
}
}
方式三:在线工具
使用 Jasypt 在线加密工具生成密文(注意:生产环境密钥和敏感信息不建议使用在线工具)。
2.4 使用加密配置
将生成的密文用 ENC(...) 包裹后,替换配置文件中的明文即可。Jasypt 会在应用启动时自动解密。
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: ENC(uxQ1JgGJ8ZbX5sW9nV2pRw==)
password: ENC(aB3dEfGhIjKlMnOpQrStUvWxYz==)
redis:
password: ENC(1234567890abcdefghijklmnopqrstuvwxyz)
注意: 加密和解密必须使用相同的密钥和算法,否则会导致解密失败。每次加密生成的密文可能不同(因为随机盐值),但都可以用同一个密钥解密。
2.5 启用加密属性
对于使用 @SpringBootApplication 或 @EnableAutoConfiguration 的项目,引入 Starter 后会自动启用加密属性,无需额外配置。
如果需要手动控制,可以在启动类或配置类上添加 @EnableEncryptableProperties 注解:
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableEncryptableProperties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. 核心配置详解
3.1 配置项列表
| 配置项 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
jasypt.encryptor.password |
是 | - | 加密 / 解密密钥 |
jasypt.encryptor.algorithm |
否 | PBEWITHHMACSHA512ANDAES_256 | 加密算法 |
jasypt.encryptor.key-obtention-iterations |
否 | 1000 | 密钥获取迭代次数 |
jasypt.encryptor.pool-size |
否 | 1 | 加密器池大小 |
jasypt.encryptor.salt-generator-classname |
否 | org.jasypt.salt.RandomSaltGenerator | 盐值生成器类名 |
jasypt.encryptor.iv-generator-classname |
否 | org.jasypt.iv.RandomIvGenerator | IV 生成器类名 |
jasypt.encryptor.string-output-type |
否 | base64 | 输出类型:base64 /hexadecimal |
jasypt.encryptor.provider-name |
否 | - | 加密服务提供者名称 |
jasypt.encryptor.provider-class-name |
否 | - | 加密服务提供者类名 |
3.2 常用加密算法
| 算法名称 | 强度 | 适用场景 | 备注 |
|---|---|---|---|
| PBEWithMD5AndDES | 低 | 兼容旧系统 | 传统算法,安全性较低 |
| PBEWithHMACSHA512AndAES_256 | 高 | 生产环境推荐 | 3.x 版本默认算法 |
| PBEWITHHMACSHA256ANDAES_128 | 中 | 受 JCE 限制环境 | 无需无限制密钥策略 |
JCE 无限制密钥策略: 使用 AES-256 算法需要 JDK 支持无限制密钥强度。JDK 8u161+、JDK 9+ 已默认支持;更早版本需要手动下载安装 JCE Unlimited Strength Jurisdiction Policy Files。Jasypt 3.0+ 版本已自动处理此问题,无需手动配置。
3.3 完整配置示例
jasypt:
encryptor:
# 加密密钥(从环境变量获取)
password: ${JASYPT_ENCRYPTOR_PASSWORD:dev-secret-key}
# 加密算法
algorithm: PBEWithHMACSHA512AndAES_256
# 密钥获取迭代次数,值越大越安全但性能越低
key-obtention-iterations: 1000
# 盐值生成器
salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
# IV 生成器(AES-GCM 模式需要)
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
# 输出格式
string-output-type: base64
# 加密器池大小
pool-size: 2
4. 高级用法
4.1 自定义加密器
当默认加密器不能满足需求时,可以通过实现 StringEncryptor 接口自定义加密逻辑。
步骤一:实现 StringEncryptor 接口
import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Component;
@Component("customStringEncryptor")
public class CustomEncryptor implements StringEncryptor {
@Override
public String encrypt(String message) {
// 自定义加密逻辑
// 示例:使用 AES 加密
return doEncrypt(message);
}
@Override
public String decrypt(String encryptedMessage) {
// 自定义解密逻辑
return doDecrypt(encryptedMessage);
}
private String doEncrypt(String message) {
// 具体加密实现...
return encrypted;
}
private String doDecrypt(String encryptedMessage) {
// 具体解密实现...
return decrypted;
}
}
步骤二:配置使用自定义加密器
jasypt:
encryptor:
bean: customStringEncryptor # 指定自定义加密器的 Bean 名称
使用配置类方式定义
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JasyptConfig {
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
// 从环境变量获取密钥
config.setPassword(System.getenv().getOrDefault("JASYPT_ENCRYPTOR_PASSWORD", "dev-key"));
config.setAlgorithm("PBEWithHMACSHA512AndAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("2");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
4.2 自定义加密前缀和后缀
默认使用 ENC(...) 作为加密属性的标识,可以自定义前缀和后缀:
jasypt:
encryptor:
property:
prefix: "DEC("
suffix: ")"
配置后,使用 DEC(密文) 格式即可:
spring:
datasource:
password: DEC(aB3dEfGhIjKlMnOpQrStUvWxYz==)
4.3 加密器懒加载
默认情况下,加密器会在应用启动时立即初始化。如果希望在首次使用时才初始化,可以配置懒加载:
jasypt:
encryptor:
lazy: true
4.4 指定加密属性来源
默认情况下,Jasypt 会对所有 Spring Environment 中的属性进行解密。可以通过配置指定只对特定的属性源进行解密:
jasypt:
encryptor:
property-sources:
- classpath:application.yml
- classpath:application-${spring.profiles.active}.yml
5. 在代码中使用
5.1 通过 @Value 注入
使用 @Value 注解注入加密属性时,获取到的是自动解密后的明文:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class DatabaseConfig {
@Value("${spring.datasource.username}")
private String username; // 自动解密后的明文
@Value("${spring.datasource.password}")
private String password; // 自动解密后的明文
public void printConfig() {
System.out.println("用户名: " + username);
System.out.println("密码: " + password);
}
}
5.2 通过 Environment 获取
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ConfigService {
@Autowired
private Environment env;
public String getDbPassword() {
// 获取到的是解密后的明文
return env.getProperty("spring.datasource.password");
}
}
5.3 通过 @ConfigurationProperties
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {
private String url;
private String username; // 自动解密
private String password; // 自动解密
// getters and setters...
}
5.4 直接使用加密器 Bean
也可以直接注入加密器 Bean,在代码中手动进行加解密操作:
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EncryptionService {
@Autowired
private StringEncryptor stringEncryptor;
public String encrypt(String plainText) {
return stringEncryptor.encrypt(plainText);
}
public String decrypt(String encryptedText) {
return stringEncryptor.decrypt(encryptedText);
}
}
6. 版本兼容性
6.1 Spring Boot 版本对应
| Spring Boot 版本 | 推荐 Jasypt 版本 | 说明 |
|---|---|---|
| 2.4.x ~ 2.7.x | 3.0.5+ | 兼容 JDK 8+,稳定可靠 |
| 3.0.x ~ 3.1.x | 3.0.5 | 兼容 Spring Boot 3.0+ |
| 3.2.x ~ 3.5.x | 4.0.4 | 3.0.5 存在兼容性问题,建议升级到 4.0.4 |
6.2 v4.x 版本变化
jasypt-spring-boot 4.x 版本主要变化包括:
-
修复了与 Spring Boot 3.2+ 的兼容性问题
-
优化了加密器初始化逻辑
-
提升了性能和稳定性
-
依赖版本升级
从 3.x 升级到 4.x 通常只需修改依赖版本号即可,配置项基本保持兼容。
7. 常见问题与排错
7.1 解密失败:EncryptionOperationNotPossibleException
现象: 应用启动时报错 EncryptionOperationNotPossibleException 或 Failed to decrypt property。
常见原因及解决方案:
-
密钥不匹配:加密时使用的密钥与解密时的密钥不一致。检查加密密钥和应用配置的密钥是否完全相同。
-
算法不匹配:加密和解密使用的算法不同。确保生成密文和项目配置使用相同的算法。
-
密文被修改:密文包含空格、换行或被手动修改。确保密文完整且未被篡改。
-
JCE 限制:JDK 不支持 256 位 AES 加密。使用 Jasypt 3.0+ 版本或安装 JCE 无限制策略文件。
-
盐值生成器不匹配:加密时使用固定盐值,解密时使用随机盐值(或反之)。确保盐值生成器配置一致。
7.2 环境变量 JASYPT_ENCRYPTOR_PASSWORD 不生效
排查步骤:
-
确认变量名拼写正确(全大写),末尾无多余空格
-
Windows 设置后需重启命令行或 IDE 方可生效
-
IntelliJ IDEA 需在 Run Configuration 中手动添加环境变量
-
使用
mvn spring-boot:run时,环境变量需在执行前导出 -
Docker 环境中需通过
-e参数传递环境变量
7.3 配置绑定失败:Failed to bind properties
现象: 启动时报错 Failed to bind properties under 'xxx' to java.lang.String。
常见原因:
-
ENC () 格式错误:密文未正确使用
ENC(...)包裹,或括号不匹配。 -
依赖缺失:未正确引入 jasypt-spring-boot-starter 依赖。
-
版本不兼容:Jasypt 版本与 Spring Boot 版本不兼容。参考版本兼容性表调整版本。
-
自定义加密器未生效:自定义加密器 Bean 名称与配置不匹配。
7.4 加密后的密文每次都不一样
原因: 这是正常现象。Jasypt 默认使用随机盐值生成器(RandomSaltGenerator),每次加密都会生成不同的盐值,因此相同明文每次加密得到的密文都不同。但这些密文都可以用同一个密钥正确解密。
如需固定密文: 可以配置使用固定盐值生成器(不推荐,安全性降低):
jasypt:
encryptor:
salt-generator-classname: org.jasypt.salt.ZeroSaltGenerator
7.5 如何验证解密是否成功
可以通过以下方式验证配置解密是否正常:
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
public class DecryptValidator implements CommandLineRunner {
private final Environment env;
public DecryptValidator(Environment env) {
this.env = env;
}
@Override
public void run(String... args) {
String password = env.getProperty("spring.datasource.password");
System.out.println("数据库密码解密结果: " + password);
// 注意:生产环境不要打印敏感信息
}
}
8. 最佳实践与安全建议
8.1 密钥管理最佳实践
-
禁止硬编码密钥:密钥绝不能出现在代码或配置文件中,更不能提交到代码仓库。
-
使用环境变量注入:生产环境优先使用环境变量或配置中心传递密钥。
-
不同环境使用不同密钥:开发、测试、生产环境使用不同的加密密钥。
-
定期轮换密钥:建立密钥轮换机制,定期更换加密密钥并重新加密配置。
-
使用配置中心:结合 Nacos、Apollo 等配置中心,实现配置的集中管理和动态更新。
8.2 代码安全
-
将 jasypt 配置文件加入
.gitignore,防止密钥泄露 -
代码审查时重点检查是否有明文敏感信息
-
CI/CD 流水线中通过环境变量注入密钥
-
Docker 部署时通过 Secrets 或环境变量传递密钥
8.3 算法选择建议
-
生产环境:推荐使用
PBEWithHMACSHA512AndAES_256,安全性高 -
兼容性优先:使用
PBEWithMD5AndDES,但安全性较低,仅用于兼容旧系统 -
迭代次数:根据性能要求适当调整,建议不低于 1000 次
-
盐值生成:始终使用随机盐值,不要使用固定盐值
8.4 与配置中心集成
Jasypt 可以与主流配置中心(Nacos、Apollo、Spring Cloud Config 等)无缝集成。配置中心存储加密后的配置,应用启动时由 Jasypt 自动解密。
集成要点:
-
确保配置中心的配置在 Jasypt 初始化之前加载
-
加密密钥通过环境变量或启动参数注入,不存放在配置中心
-
配置更新后,需确保加密器能正确解密新配置
9. 总结
jasypt-spring-boot 是 Spring Boot 项目中实现配置加密的成熟方案,通过简单的配置即可保护敏感配置信息。使用时需注意以下关键点:
-
选择合适的版本,确保与 Spring Boot 版本兼容
-
妥善保管加密密钥,生产环境使用环境变量注入
-
加密和解密使用相同的密钥和算法
-
定期轮换密钥,建立安全管理机制
-
结合配置中心使用,实现更完善的配置管理
通过合理使用 jasypt-spring-boot,可以在不侵入业务代码的前提下,显著提升应用配置的安全性,是企业级应用开发的必备安全组件。
(注:部分内容可能由 AI 生成)
除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接


文章评论