Spring Boot 配置加密从入门到入狱:别再让密码裸奔了!
一、为什么需要配置加密?
在Spring Boot项目开发中,我们通常会在application.yml或application.properties中配置各种敏感信息,包括:
-
数据库连接密码
-
Redis连接密码
-
第三方API密钥
-
邮箱服务密码
-
各种中间件认证信息
安全风险:如果这些敏感信息以明文形式存储在配置文件中,一旦代码仓库泄露或配置文件被非法获取,将直接导致系统安全漏洞,可能造成数据泄露、服务被入侵等严重后果。
解决方案:使用Jasypt(Java Simplified Encryption)对配置文件中的敏感信息进行加密处理。

二、Jasypt简介
Jasypt是一个Java加密库,提供了简单易用的加密/解密功能,主要特点包括:
-
支持单向和双向加密
-
与Spring Boot无缝集成
-
支持多种加密算法
-
配置简单,开箱即用
-
支持自定义加密器
三、Spring Boot集成Jasypt完整步骤
3.1 引入依赖
在pom.xml中添加Jasypt Spring Boot Starter依赖:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
版本说明:3.0.4是目前最稳定的版本,支持Spring Boot 2.x和3.x系列。
3.2 配置加密密钥
在application.yml中配置Jasypt加密密钥:
jasypt:
encryptor:
# 加密密钥(生产环境建议通过环境变量或启动参数传入)
password: your-secret-key-here
# 加密算法
algorithm: PBEWithMD5AndDES
# 密钥获取迭代次数
iv-generator-classname: org.jasypt.iv.NoIvGenerator
重要提示:加密密钥是整个加密体系的核心,千万不要硬编码在配置文件中!生产环境建议通过以下方式传入:
-
启动参数:
--jasypt.encryptor.password=your-key -
环境变量:
JASYPT_ENCRYPTOR_PASSWORD=your-key -
系统属性:
-Djasypt.encryptor.password=your-key
3.3 生成加密密码
有多种方式可以生成加密后的密码,这里介绍两种最常用的方法:
方法一:使用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-here"); // 加密密钥
encryptor.setAlgorithm("PBEWithMD5AndDES");
// 加密数据库密码
String dbPassword = encryptor.encrypt("123456");
System.out.println("数据库加密密码: ENC(" + dbPassword + ")");
// 加密Redis密码
String redisPassword = encryptor.encrypt("redis123");
System.out.println("Redis加密密码: ENC(" + redisPassword + ")");
}
}
方法二:使用Maven插件生成
mvn jasypt:encrypt-value -Djasypt.encryptor.password=your-secret-key -Djasypt.plugin.value=123456
四、数据库密码加密实战
4.1 加密前的配置(明文)
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db
username: root
password: 123456 # 明文密码,不安全!
driver-class-name: com.mysql.cj.jdbc.Driver
4.2 加密后的配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db
username: root
password: ENC(9Lm3nQpR7sT2vW8xY4zA6bC9dE1fG5hJ) # 加密后的密码
driver-class-name: com.mysql.cj.jdbc.Driver
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD:} # 从环境变量读取密钥
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
格式说明:加密后的密码需要用ENC()包裹,Jasypt会自动识别并解密。
五、Redis密码加密实战
5.1 加密前的Redis配置
spring:
redis:
host: localhost
port: 6379
password: redis123 # 明文密码
database: 0
timeout: 3000ms
5.2 加密后的Redis配置
spring:
redis:
host: localhost
port: 6379
password: ENC(KjH8gF6dS4aD2fG1hJ3kL5mN7bV9cX2z) # 加密后的密码
database: 0
timeout: 3000ms
六、其他常见加密场景
6.1 邮箱服务密码加密
spring:
mail:
host: smtp.qq.com
port: 587
username: your-email@qq.com
password: ENC(MnQ8pR2sT4wY6aZ8cB0dE2fG4hJ6kL8m) # 邮箱授权码加密
properties:
mail:
smtp:
auth: true
starttls:
enable: true
6.2 第三方API密钥加密
# 阿里云OSS配置
aliyun:
oss:
endpoint: oss-cn-beijing.aliyuncs.com
access-key-id: ENC(AaS1dF2gH3jK4lM5nO6pQ7rS8tU9vW0x)
access-key-secret: ENC(ZxQ9wE8rT7yU6iO5pA4sD3fG2hJ1kL0m)
bucket-name: your-bucket-name
6.3 自定义配置项加密
# 自定义业务配置
app:
security:
jwt-secret: ENC(JwT2sE4cR6eT8kE0yN2oW4l6d8f0g2h4)
admin-password: ENC(AdM1iN3pA5sS7wO9rD2k4e6y8)
七、高级配置与自定义
7.1 使用更强的加密算法
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD}
algorithm: PBEWithHMACSHA512AndAES_256
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
pool-size: 2
salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
string-output-type: base64
7.2 自定义加密前缀和后缀
如果不想使用默认的ENC()格式,可以自定义:
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD}
property:
prefix: "DEC["
suffix: "]"
然后配置文件中使用:
spring:
datasource:
password: DEC[加密后的密码字符串]
7.3 自定义加密器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("JASYPT_ENCRYPTOR_PASSWORD"));
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
八、JDK版本与加密能力兼容性
Jasypt加密能力与JDK版本密切相关,不同版本的JDK对加密算法的支持程度存在显著差异。这是很多开发者在实际使用中容易踩坑的地方。
8.1 JDK版本加密能力差异
| JDK版本 | 默认加密能力 | 是否需要JCE |
|---|---|---|
| JDK 8u151及更早 | 仅支持128位加密 | ✅ 必须安装JCE才能支持256位 |
| JDK 8u161+ / 8u171+ | 默认支持256位加密 | ❌ 无需额外配置 |
| JDK 9 及以上 | 默认支持256位加密 | ❌ 无需额外配置 |
关键区别:JDK 8u151及更早版本由于美国出口限制政策,默认禁用了256位高强度加密算法,必须手动安装JCE(Java Cryptography Extension)无限制权限策略文件才能使用。
8.2 各JDK版本推荐算法选择
低版本JDK(8u151及更早,未安装JCE)
只能使用128位及以下的加密算法:
jasypt:
encryptor:
# 安全兼容的算法(无需JCE)
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
# 或使用PBEWithMD5AndTripleDES(168位,部分JDK默认支持)
高版本JDK(8u161+ / 9+,或已安装JCE)
推荐使用更强的256位加密算法:
jasypt:
encryptor:
# 推荐:AES-256高强度加密
algorithm: PBEWithHMACSHA512AndAES_256
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
# 备选方案
# algorithm: PBEWithSHA256AndAES_128
# algorithm: PBEWithSHA1AndDESede
8.3 JCE无限制权限策略文件安装步骤
步骤1:下载JCE文件
官方下载地址:
-
JDK 8:https://www.oracle.com/java/technologies/javase-jce8-downloads.html
-
JDK 7:https://www.oracle.com/java/technologies/javase-jce7-downloads.html
下载文件:UnlimitedJCEPolicyJDK8.zip
步骤2:解压并放置文件
Windows系统:
# 1. 找到JDK安装目录(示例)
cd C:\Program Files\Java\jdk1.8.0_144\jre\lib\security
# 2. 备份原文件
copy local_policy.jar local_policy.jar.bak
copy US_export_policy.jar US_export_policy.jar.bak
# 3. 将解压后的两个jar文件复制到security目录,覆盖原文件
Linux/Mac系统:
# 1. 找到JDK安装目录
cd $JAVA_HOME/jre/lib/security
# 2. 备份原文件
cp local_policy.jar local_policy.jar.bak
cp US_export_policy.jar US_export_policy.jar.bak
# 3. 复制新文件(假设解压到~/Downloads/jce/)
cp ~/Downloads/jce/UnlimitedJCEPolicy/*.jar .
步骤3:验证JCE安装成功
创建验证Java程序:
import javax.crypto.Cipher;
public class JceCheck {
public static void main(String[] args) {
try {
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
System.out.println("AES最大密钥长度: " + maxKeyLen);
if (maxKeyLen >= 256) {
System.out.println("✅ JCE无限制权限已启用!支持256位加密");
} else {
System.out.println("❌ JCE未安装,仅支持" + maxKeyLen + "位加密");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行验证:
javac JceCheck.java && java JceCheck
成功输出:
AES最大密钥长度: 2147483647
✅ JCE无限制权限已启用!支持256位加密
8.4 常见JCE相关错误及解决方案
错误1:EncryptionOperationNotPossibleException
错误信息:
org.jasypt.exceptions.EncryptionOperationNotPossibleException:
Encryption raised an exception. A possible cause is you are using strong encryption
algorithms and you have not installed the Java Cryptography Extension (JCE)
Unlimited Strength Jurisdiction Policy Files in this Java Virtual Machine
原因:使用了需要256位支持的加密算法,但JDK未安装JCE
解决方案:
-
安装JCE无限制权限策略文件(见8.3节)
-
或降级使用兼容算法:
PBEWithMD5AndDES
错误2:Illegal key size or default parameters
错误信息:
java.security.InvalidKeyException: Illegal key size or default parameters
原因:密钥长度超过JDK默认限制(通常是尝试使用256位密钥)
解决方案:
-
安装JCE(推荐)
-
或在Java启动参数中添加:
java -Dcrypto.policy=unlimited -jar your-app.jar
错误3:BadPaddingException / GeneralSecurityException
错误信息:
javax.crypto.BadPaddingException: Given final block not properly padded
java.security.GeneralSecurityException: javax.crypto.BadPaddingException
可能原因:
-
加密和解密使用的JDK环境不一致(一个装了JCE一个没装)
-
加密时用了256位算法,解密时JDK不支持
-
IV(初始化向量)配置不匹配
解决方案:
-
确保所有环境(开发/测试/生产)都安装JCE
-
统一加密算法配置,特别是
iv-generator-classname -
使用
NoIvGenerator提高兼容性:jasypt: encryptor: iv-generator-classname: org.jasypt.iv.NoIvGenerator
8.5 Docker容器JCE配置方案
如果应用运行在Docker容器中,可在Dockerfile中预装JCE:
FROM openjdk:8-jdk-alpine
# 安装JCE无限制权限(针对8u151之前的镜像)
RUN wget -q --no-check-certificate --no-cookies \
--header "Cookie: oraclelicense=accept-securebackup-cookie" \
"https://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip" -O /tmp/jce.zip \
&& unzip /tmp/jce.zip -d /tmp/ \
&& cp /tmp/UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jre/lib/security/ \
&& rm -rf /tmp/jce.zip /tmp/UnlimitedJCEPolicyJDK8
# 或者对于较新镜像,直接设置系统属性
ENV JAVA_OPTS="$JAVA_OPTS -Dcrypto.policy=unlimited"
COPY target/your-app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
最佳实践建议:
-
优先升级到JDK 8u161+或JDK 11/17,默认支持无限制加密
-
如必须使用旧JDK,务必在所有环境统一安装JCE
-
使用
PBEWithMD5AndDES算法获得最大兼容性 -
部署前务必运行JCE验证程序确认配置正确
九、常见问题与解决方案
9.1 问题一:解密失败,提示"Unable to decrypt property"
原因:
-
加密密钥不匹配
-
加密算法配置不一致
-
加密字符串格式错误
解决方案:
# 1. 确保加密和解密使用相同的密钥
# 2. 确保算法配置一致
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
# 3. 检查ENC()格式是否正确,不要有多余空格
9.2 问题二:Spring Boot 3.x兼容性问题
原因:Spring Boot 3.x使用Jakarta EE,部分旧版本Jasypt不兼容。
解决方案:使用3.0.4及以上版本
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
9.3 问题三:单元测试时如何处理加密配置
解决方案:在测试配置中指定密钥
@SpringBootTest(properties = "jasypt.encryptor.password=test-key")
public class ApplicationTests {
@Test
void contextLoads() {
}
}
9.4 问题四:如何在开发环境禁用加密
解决方案:使用profile区分环境
# 开发环境使用明文
jasypt:
encryptor:
bootstrap: false # 禁用Jasypt自动配置
十、生产环境最佳实践
10.1 密钥安全管理
绝对禁止将加密密钥提交到代码仓库!
推荐方案:
-
环境变量方式(最推荐):
# Linux/Mac export JASYPT_ENCRYPTOR_PASSWORD="your-production-key" # Windows set JASYPT_ENCRYPTOR_PASSWORD=your-production-key # Docker docker run -e JASYPT_ENCRYPTOR_PASSWORD=your-production-key your-image -
启动参数方式:
java -jar your-app.jar --jasypt.encryptor.password=your-production-key -
K8s Secret方式:
env: - name: JASYPT_ENCRYPTOR_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: jasypt-password
10.2 多环境配置策略
| 环境 | 配置方式 | 说明 |
|---|---|---|
| 开发环境 | 明文或简单加密 | 便于开发调试 |
| 测试环境 | 完整加密 | 验证加密流程 |
| 生产环境 | 强加密+环境变量密钥 | 最高安全级别 |
10.3 日志安全配置
防止配置信息被打印到日志:
logging:
level:
com.ulisesbocchio.jasyptspringboot: WARN
org.jasypt: WARN
10.4 定期轮换密钥
建议每3-6个月轮换一次加密密钥:
-
使用旧密钥解密所有配置项
-
使用新密钥重新加密
-
更新环境变量中的密钥
-
重启应用验证
十一、完整示例项目结构
spring-boot-encryption-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── Application.java
│ │ │ ├── config/
│ │ │ │ └── JasyptConfig.java
│ │ │ └── util/
│ │ │ └── EncryptUtil.java
│ │ └── resources/
│ │ ├── application.yml
│ │ ├── application-dev.yml
│ │ ├── application-test.yml
│ │ └── application-prod.yml
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── EncryptTest.java
└── pom.xml
十二、总结
通过Jasypt实现Spring Boot配置加密是保护系统敏感信息的有效手段。核心要点:
-
集成简单:只需引入starter依赖,几行配置即可使用
-
密钥安全:生产环境务必使用环境变量传递密钥,禁止硬编码
-
覆盖全面:支持数据库、Redis、邮箱、第三方API等所有配置项
-
环境隔离:使用Spring Profile实现多环境差异化配置
-
定期维护:定期轮换密钥,保持系统安全性
更多推荐

所有评论(0)