jasypt 配置文件加密接入记录

jasypt 配置文件加密接入记录

新来的同事接手项目,第一件事是看 application.yml,然后过来问我:”数据库密码直接写在这里没问题吗?”

他说得对。项目跑了一年多,数据库密码、Redis 密码、第三方 API Key 全是明文,所有有仓库权限的人都能看到。内网项目风险暂时小,但这是隐患,审计时也会被标出来。于是接入了 jasypt 解决这个问题。


一、问题背景

为什么选 jasypt 而不是其他方案:

  • Spring Cloud Config + Vault:太重,为了加密几个密码引入一套配置中心不划算
  • 自己实现解密 Bean:重复造轮子,且团队间不统一
  • jasypt-spring-boot-starter:一个依赖搞定,ENC() 包裹密文,对业务代码零侵入,接入成本极低

适用场景:Spring Boot 项目,application.yml 里有需要保护的敏感信息(密码、API Key、Token)。


二、接入步骤

引入依赖

<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>

生成加密串

推荐写一个单元测试来生成,比命令行方式更方便日常使用:

@SpringBootTest
class JasyptTest {

@Autowired
private StringEncryptor encryptor;

@Test
void encrypt() {
// 替换成要加密的明文
String encrypted = encryptor.encrypt("your_db_password");
System.out.println("ENC(" + encrypted + ")");
}

@Test
void decrypt() {
// 验证解密是否正常
String decrypted = encryptor.decrypt("加密后的密文字符串");
System.out.println(decrypted);
}
}

命令行方式(临时生成时用):

java -cp jasypt-3.0.5.jar \
org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \
input="your_password" \
password="your_secret_key" \
algorithm=PBEWITHHMACSHA512ANDAES_256

配置文件替换

spring:
datasource:
password: ENC(jHk4MxvS9fR3Ac...) # 替换成生成的密文
redis:
password: ENC(xYqN8pBc2wL6Zm...)

jasypt:
encryptor:
# 密钥从环境变量读取,绝对不能写在配置文件里
password: ${JASYPT_ENCRYPTOR_PASSWORD}
# 生产环境换更安全的算法(默认 PBEWithMD5AndDES 安全性不够)
algorithm: PBEWITHHMACSHA512ANDAES_256
iv-generator-classname: org.jasypt.iv.RandomIvGenerator

启动时设置环境变量:

# Linux / Mac
export JASYPT_ENCRYPTOR_PASSWORD=your_secret_key
java -jar app.jar

三、密钥管理——这才是重点

加密了配置文件,如果密钥本身也在 Git 里,等于没加密。

方式一:环境变量(推荐,大多数场景够用)

在操作系统或容器启动脚本里设置 JASYPT_ENCRYPTOR_PASSWORD,不进 Git,对业务代码无感知。

方式二:启动参数(可用,但注意安全)

java -jar app.jar --jasypt.encryptor.password=xxx

ps aux 命令可以看到进程参数,在多人共享的服务器上有泄露风险,不推荐。

方式三:K8s Secret(推荐,云原生场景)

# 创建 Secret
kubectl create secret generic jasypt-key --from-literal=password=your_key

# Deployment 中注入为环境变量
env:
- name: JASYPT_ENCRYPTOR_PASSWORD
valueFrom:
secretKeyRef:
name: jasypt-key
key: password

核心原则:密钥和密文分开存放,密钥不进代码仓库。


四、CI/CD 流水线中的处理

以 Jenkins 为例:

  1. Manage Credentials 里添加 Secret Text 类型的凭证,存入 jasypt 密钥
  2. Jenkinsfile 中注入为环境变量:
pipeline {
environment {
JASYPT_ENCRYPTOR_PASSWORD = credentials('jasypt-encryptor-password')
}
stages {
stage('Deploy') {
steps {
sh 'java -jar app.jar'
// 环境变量已由 Jenkins 注入,应用启动时自动读取
}
}
}
}

GitLab CI 类似:在项目 Settings → CI/CD → Variables 里添加 JASYPT_ENCRYPTOR_PASSWORD,设为 Protected + Masked,Runner 执行时自动注入到环境变量。


五、注意事项

算法选择:默认的 PBEWithMD5AndDES 安全性较弱(MD5 已被列为不安全),生产环境务必改为 PBEWITHHMACSHA512ANDAES_256,Spring Boot 2.x 以上均支持。

密钥遗失:jasypt 没有密钥找回机制,密钥一旦丢失,所有密文无法解密,只能重新生成所有密文。密钥需要安全存档(存入团队的密码管理工具,如 1Password、Bitwarden)。

多环境密钥分离:开发、测试、生产使用不同的密钥。同一个明文密码用不同密钥加密后,密文是不同的。

Spring Boot 3.x 兼容jasypt-spring-boot-starter 3.0.5 支持 Spring Boot 2.x;Spring Boot 3.x 需升级到 3.0.5 以上版本,或使用社区适配版,接入前确认版本兼容性。

密文格式识别:jasypt 通过 ENC(...) 前缀识别需要解密的配置项,括号内是 Base64 编码的密文,直接写进 yaml 配置即可,框架在 Spring 上下文初始化时自动解密替换。