先说说我为什么要把这篇文章写下来。之前的某次项目交接中,我接手了一套遗留系统,打开application.yml一看,数据库账号密码、Redis密码、第三方支付密钥清清楚楚躺在里面,甚至还有生产环境的配置。当时后背一凉——这意味着任何一个拿到代码仓库权限的人,都能直接连上生产库。更麻烦的是,这套系统已经在线上跑了两三年,改配置牵一发动全身。后来我花了差不多一个周末,用Jasypt把整套配置加密撸了一遍,才算是把这个问题堵住。
这就是今天要聊的内容:Spring Boot配置加密,以及Jasypt加解密命令的完整用法。这篇文章不是官方文档的翻译,而是一个踩过坑、来回折腾过的人的实操总结。内容包括核心概念讲解、集成步骤、命令行加解密方法、常见坑位排查,以及我个人的安全实践建议。无论你是刚接触配置加密的新手,还是已经引入Jasypt但遇到诡异问题的老手,建议都花几分钟过一遍。
1. 整体设计与方案选型:为什么非加密不可
1.1 明文配置的真实风险
先说一个基本事实:只要配置文件里出现明文密码,你的系统基本等于裸奔。很多人觉得“内网环境没事”“代码仓库是私有的”,但实际风险比想的大得多:
- 代码仓库的权限往往比服务器权限开放得多,尤其是跨团队协作、外包参与的项目,仓库访问者远超运维范围。
- 日志、监控系统、CI/CD流水线里都可能意外泄露配置文件内容。
- 离职员工的本地副本、讨论群里的截图,都是泄露途径。
- 即便上了私有仓库,代码托管平台自身的安全事件也不是没发生过。
我自己做过一次最简单的验证:把线上应用的配置文件和代码仓库里的对比,数据库密码竟然完全一致,而且这个仓库在内部是默认对全公司开放的。发现问题之后,我第一时间改了密码、加了加密方案,过程并不复杂,但能拖一天就多一天风险。
1.2 为什么选Jasypt做Spring Boot加密
Java生态里做配置加密,主流的方案其实不多:Spring Cloud Config自带的加解密、HashiCorp Vault这类专业的密钥管理服务、以及Jasypt。
我的选型逻辑是这样的:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Jasypt | 集成Spring Boot非常轻量,加密/解密配置后可直接用ENC()包裹密文,改动最小 | 密钥管理需要自己负责 | 中小型项目、单体/微服务都适用 |
| Spring Cloud Config加解密 | 自带对称加密,配合配置中心好用 | 必须引入配置中心,架构变重 | 已经上了配置中心的团队 |
| Vault | 功能强大,支持动态密钥、细粒度权限控制 | 独立部署运维成本高,学习曲线陡 | 大型团队、安全要求极高的场景 |
对于大多数团队和项目来说,Jasypt是性价比最高的方案。它最大的优势在于侵入性极低:你不需要改造配置加载逻辑,不需要改变配置文件的结构,只需要把敏感字段的值替换成ENC(...)格式的密文,启动时框架会自动解密。团队成员甚至无需理解解密细节,照常写代码就行。
1.3 加密方案的总体思路
这篇博文要构建的,是一个完整的配置加密落地方案,而不是只教命令怎么敲。整体思路分四层:
- 选好算法和参数:Jasypt支持多种PBE算法,核心参数是加密算法、密钥(salt)、迭代次数。这一层决定了密文强度和破解难度。
- 引入依赖并配置Spring Boot集成:让应用启动时自动识别
ENC()占位符并完成解密。 - 掌握加解密命令:用命令行工具或自写工具类生成密文,方便日常操作和团队协作。
- 密钥管理和安全加固:加密密钥不能写死在配置文件里,必须通过环境变量、启动参数或外部KeyStore注入,并做好权限控制。
按这个顺序走下来,一个生产可用的配置加密方案就成型了。
2. Jasypt核心原理拆解:看不懂这些就没法排查问题
2.1 Jasypt是什么,和Spring Boot怎么协作
Jasypt(Java Simplified Encryption)是一个Java加密库,提供高强度的密码学加密功能,并且专门做了与Spring Boot的集成模块——jasypt-spring-boot-starter。它的工作方式一句话总结:拦截Spring Environment的配置读取过程,把形如ENC(密文)的值自动解密后再注入到应用里。
这里有个重要的细节:Jasypt的解密发生在Spring容器启动阶段,是在@Value注入、@ConfigurationProperties绑定之前完成的。也就是说,你的业务代码无感知,它拿到手的就是解密后的明文。这也是Jasypt集成度高的核心原因。
2.2 加密算法与核心参数
Jasypt并不是只能用某一种固定算法,它基于JCE(Java Cryptography Extension)实现,支持多种PBE(Password Based Encryption)算法。常见的有:
PBEWithMD5AndDESPBEWithSHA1AndDESedePBEWithHMACSHA512AndAES_256(推荐)
为什么推荐PBEWITHHMACSHA512ANDAES_256?因为它的设计最合理:AES-256保证加密强度和密文紧凑性,HMAC-SHA512保证数据完整性(防篡改),SHA-512负责从口令派生密钥时的混淆。相比之下,老的DES算法已经不安全,碰撞和暴力破解的成本都在快速下降,新项目不应该再用。
Jasypt的参数需要理解这四个:
- password(加密口令/密钥):加密解密都必须一致的密钥,相当于保险箱的钥匙。它不是直接用来做AES的原始密钥,而是参与KDF派生。
- salt(盐值):一段随机数据,在加密时生成,和解密密文拼接在一起。它保证同一个明文、同一个密钥,每次生成的密文都不一样。这块很关键——如果没有随机盐,攻击者可以通过彩虹表或者模式匹配直接识别出相同明文。
- iteration(迭代次数):对密钥进行多少次哈希迭代,提高暴力破解成本。默认值因算法而异,一般1000次起步,越高越安全但性能会差一点。
- IV(Initialization Vector,初始向量):某些算法(如AES-CBC/GCM)加密时引入的随机向量,保证密码块链的随机性。Jasypt里用
RandomIvGenerator生成。
用生活化类比理解:password是抽屉钥匙,salt是你在钥匙上额外加的一层随机迷惑胶带,iteration是反复涂胶带的次数,IV是每次开抽屉时随机转的锁孔偏移。破解者就算拿到密文,也不知道你的钥匙长什么样、偏移了几格。
2.3 加密与解密流程示意
加密时,Jasypt内部做的事情大致这样:
明文 + password + 随机salt ---> KDF派生密钥 ---> AES-256加密 ---> salt + IV + 密文解密时,正好反过来:
salt + IV + 密文 ---> 从密文中提取salt和IV ---> 用password+提取的salt重新派生密钥 ---> 解密得到明文注意解密时的盐值不是你自己传的,而是从密文中提取的。很多人初次用命令行解密时总想把加密时的salt传进去,结果反而解不开,这就是没搞懂流程。
2.4 密文格式ENC()如何被识别
Spring Boot集成后,Jasypt会自动扫描所有配置值的字符串,如果匹配ENC(...)模式就执行解密,替换为解密结果,然后再让Spring正常注入。嵌套场景也支持,比如ENC(密文A)拼接ENC(密文B)会在整个字符串级别完成替换。
有一个容易忽视的地方:如果某个配置项的值确实以字面量ENC开头,且不加括号,不受影响;但如果你的某个普通字符串恰好以ENC(开头、以)结尾,可能会被误解密。概率极低,但写代码时心里有数。
3. Spring Boot集成实操:从依赖到跑通的完整步骤
3.1 引入依赖与版本选择
以Maven项目为例,在pom.xml中加入:
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.5</version> </dependency>版本选择上,3.0.x对应的Jasypt核心库版本比较高,默认算法已经变成了PBEWITHHMACSHA512ANDAES_256。如果你用的是旧项目,之前可能接触的是低版本,默认算法是老旧的PBEWITHMD5ANDDES。升级版本后,密文需要用新算法重新生成,这点务必注意,我之前就在升级时栽过跟头——老的密文全都解不开,排查了半天才发现是默认算法变了。
3.2 配置加密参数
在application.yml中添加Jasypt配置。我的推荐配置如下:
jasypt: encryptor: password: ${JASYPT_PASSWORD} algorithm: PBEWITHHMACSHA512ANDAES_256 iv-generator-classname: org.jasypt.iv.RandomIvGenerator这里有两个重点提示:
- 密钥不要硬编码在配置文件里。上面我用了
${JASYPT_PASSWORD},表示从环境变量读取。你可以在启动脚本里export JASYPT_PASSWORD=你的密钥,或者部署平台(比如K8s的Secret)注入。硬编码在yaml里等于把钥匙放在锁旁边,加密就失去意义了。 - 算法和IV生成器必须跟命令行加密时用的参数完全一致,否则解密必失败。
如果用的是jasypt-spring-boot-starter,默认配置够了;但如果你的Spring Boot是2.x以下的老版本,或者遇到自定义配置不生效的情况,需要引入jasypt-spring-boot而非starter,并在启动类上加@EnableEncryptableProperties注解,显式开启加密属性支持。
3.3 生成密文并替换配置
先假设一个待加密的数据库密码明文为MyStrongDbPass2024。我会在下一章详细讲解命令,这里先直接给结果,密文大概长这样:
spring: datasource: url: jdbc:mysql://localhost:3306/order_db username: order_admin password: ENC(4R9FUVycM6J+hYxMp6TzSXFRnq7XOIfjmlBMAXnQpMQ++sJXhLP1DZw3PsMxhVQx)其他敏感项同理:
redis: password: ENC(NxVgE5Hq9dFKfPlP4rW8K6BJz1QVWJktXaFzTsOaUeg=) third-party: pay-sign-key: ENC(U4Gv9qaLoY6vv/2sL3Zz0p6u8BKnkH8I7Rc0BwXWXKw=)这样改完,配置文件的明文秘密就全部变成了密文。把这份配置提交到代码仓库,泄露风险立刻大幅降低。
3.4 验证是否解密成功
启动应用后,你会在日志里看到类似这样的内容:
Encryptable properties detected: password, redis password, pay-sign-key说明Jasypt已经识别到加密属性。怎么确认解密成功?最简单的办法是临时写一个接口或者用ApplicationRunner打印:
@Component public class ConfigPrinter implements ApplicationRunner { @Value("${spring.datasource.password}") private String dbPassword; @Override public void run(ApplicationArguments args) { System.out.println("DB password decrypted: " + dbPassword); } }看到打印结果是明文MyStrongDbPass2024,说明解密链路通畅。确认之后再把这段代码删掉,不要留在生产代码里打日志泄漏密码。
3.5 实战中配置多个加密器
默认配置下,所有ENC()都用同一个加密器和同一套密钥。如果你的项目里不同模块需要隔离密钥(比如支付密钥和数据库密码用不同的钥匙),Jasypt也支持多加密器。做法是自定义多个StringEncryptor实现Bean,并指定不同的配置前缀。
@Bean(name = "payEncryptor") public StringEncryptor payEncryptor() { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256"); encryptor.setPassword("支付模块专用密钥"); encryptor.setIvGenerator(new RandomIvGenerator()); return encryptor; }然后配置时手动指定:
third-party: pay-sign-key: ENC(hQH7sLxSXF/2LQ3rzbZ6XlbuCY6TpRmMDeYn4bQ3NPU=, payEncryptor)ENC(密文, 加密器Bean名)这种写法就直接指定了用payEncryptor解密。这种方式适合安全域划分明确的团队,但不建议一开始就上,复杂度会高一些。
4. 加解密命令实操:命令行、工具类与脚本封装
4.1 用Jasypt自带Jar包执行加密命令
Jasypt发布包里自带命令行工具类,适合本地临时加密或者写脚本。首先下载jasypt-1.9.3.jar(版本以官方为准),然后在命令行执行:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \ input="MyStrongDbPass2024" \ password="YourMasterKey" \ algorithm=PBEWITHHMACSHA512ANDAES_256 \ ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator执行后输出大概长这样:
----ENVIRONMENT---------------- Runtime: OpenJDK 64-Bit Server VM 17.0.5 ----ARGUMENTS------------------- input: MyStrongDbPass2024 ... ----OUTPUT---------------------- 4R9FUVycM6J+hYxMp6TzSXFRnq7XOIfjmlBMAXnQpMQ++sJXhLP1DZw3PsMxhVQx这个输出就是密文,直接拿去替换配置。
解密命令对应为:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI \ input="4R9FUVycM6J+hYxMp6TzSXFRnq7XOIfjmlBMAXnQpMQ++sJXhLP1DZw3PsMxhVQx" \ password="YourMasterKey" \ algorithm=PBEWITHHMACSHA512ANDAES_256 \ ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator注意:解密命令不需要也不能传入salt、IV——这些是从密文中自动提取的。如果你看到输出里带了类似----OUTPUT------后面跟着另一串字符,那就是解密结果。
提示:命令行中的
password是加密口令,不要跟密码学领域的“密码”概念混淆。它本质上是你的主密钥,泄露了等于所有密文全部解开。
4.2 自己写一个加解密工具类
每次用jar包敲命令有个痛点:参数太长,容易敲错,而且团队成员不一定有jar包。我推荐自己写一个极简的Java工具类,放到工程的src/test/java里或者单独的工具项目里,几行代码搞定,而且能确保和项目里用的Jasypt版本完全一致。
import org.jasypt.util.text.BasicTextEncryptor; public class JasyptTool { public static void main(String[] args) { BasicTextEncryptor encryptor = new BasicTextEncryptor(); encryptor.setPassword("YourMasterKey"); String plainText = "MyStrongDbPass2024"; String encrypted = encryptor.encrypt(plainText); System.out.println("密文: " + encrypted); String decrypted = encryptor.decrypt(encrypted); System.out.println("明文: " + decrypted); } }不过注意,BasicTextEncryptor底层用的是PBEWithMD5AndDES,这个算法已经偏弱。如果你生产配置里用的是PBEWITHHMACSHA512ANDAES_256,建议用PooledPBEStringEncryptor写一个和配置完全对齐的版本:
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; import org.jasypt.iv.RandomIvGenerator; public class AesJasyptTool { public static void main(String[] args) { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256"); encryptor.setPassword("YourMasterKey"); encryptor.setIvGenerator(new RandomIvGenerator()); String plainText = "MyStrongDbPass2024"; String encrypted = encryptor.encrypt(plainText); System.out.println("密文: " + encrypted); String decrypted = encryptor.decrypt(encrypted); System.out.println("明文: " + decrypted); } }PooledPBEStringEncryptor相比StandardPBEStringEncryptor会维护一个加解密线程池,在多线程场景下性能更好。工具类我建议用这种写法,因为它把算法、IV生成器都显式写出来了,和Spring Boot配置对得上,不用记一堆命令行参数。
4.3 用Shell脚本封装日常命令
命令行工具和工具类各有利弊:命令通用性强,工具类跟项目版本一致。我在团队里落地的时候,又封装了一层Shell脚本,放在工程根目录的bin/encrypt.sh里,方便同事一键加解密,也不用了解底层细节:
#!/bin/bash # 用法: ./encrypt.sh enc '明文' 或 ./encrypt.sh dec '密文' JASYPT_JAR=libs/jasypt-1.9.3.jar MASTER_KEY=${JASYPT_PASSWORD:-default_dev_key} if [ "$1" == "enc" ]; then java -cp "$JASYPT_JAR" org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \ input="$2" \ password="$MASTER_KEY" \ algorithm=PBEWITHHMACSHA512ANDAES_256 \ ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator elif [ "$1" == "dec" ]; then java -cp "$JASYPT_JAR" org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI \ input="$2" \ password="$MASTER_KEY" \ algorithm=PBEWITHHMACSHA512ANDAES_256 \ ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator else echo "Usage: $0 {enc|dec} value" fi这里有个注意点:如果直接export JASYPT_PASSWORD,脚本会自动读取环境变量里的密钥;如果环境变量没设置,脚本里有个default_dev_key的默认值兜底。但生产环境千万不要依赖这个默认值,我加它只是为了本地开发的便利。团队里可以约定:本地开发密钥放.env文件不入库,CI/CD里通过Secret注入真实密钥。
4.4 多环境配置下的密文管理
不同环境(dev、test、prod)是否要用不同的主密钥?我的建议是:至少生产环境必须独立密钥。开发环境的密钥可以放心的写在开发文档里,即使泄露了也只是开发库。生产环境的密钥要么用K8s Secret、要么用部署平台的变量注入,绝不能出现在任何配置文件或脚本里。
配置层面可以用Spring Profile区分:
# application-dev.yml jasypt: encryptor: password: ${JASYPT_PASSWORD:dev_local_key} # application-prod.yml jasypt: encryptor: password: ${JASYPT_PASSWORD}同一个密文在不同环境能不能共用?技术上可以,所有环境用同一个主密钥加密的密文,在任何一个环境里都能解开。但出于密钥隔离的考虑,生产环境最好用独立密钥重新生成密文。实际操作中比较繁琐,很多团队为了省事共用密钥,从纯安全角度这件事不推荐,但你的团队如果已经有严格的密钥管理流程,分环境密钥是顺理成章的事。
5. 常见问题与排查技巧实录
5.1 解密异常:Decryption failed或Cannot decrypt
这是遇到最多的报错,基本可以归纳为四类:
| 问题 | 可能原因 | 排查方法 |
|---|---|---|
Decryption failed | 密钥不一致 | 检查加密时的password和配置里的jasypt.encryptor.password是否完全一致 |
Algorithm not found | 算法名拼错或JDK不支持 | 确认算法名是全大写格式,如PBEWITHHMACSHA512ANDAES_256;老JDK可能需要额外安装JCE |
IV not available | 加密时用了IV,解密配置没配 | 确保配置文件里有iv-generator-classname: org.jasypt.iv.RandomIvGenerator |
| 低版本兼容问题 | Jasypt 3.x换了默认算法 | 老的密文需要用新算法重新加密 |
最典型的一个场景:某个同事在本地用命令行加密时没指定ivGeneratorClassName,默认用的是NoIvGenerator,结果生产配置里是RandomIvGenerator,两边算法算出来的密文结构完全不同,自然解不开。所以加密命令的每个参数都必须和Spring Boot配置里的参数逐项对齐。
5.2 密钥泄露与配置安全问题
大家最容易踩的坑是把密钥写进application.yml里。有些文章为了演示方便会这么写,这在本地跑demo没问题,但千万不能依赖这个习惯。
密钥管理的正确做法:
- 环境变量注入:
${JASYPT_PASSWORD}从环境变量读取,启动脚本里export。 - 部署平台Secret:K8s里用Secret挂载为环境变量,云平台用配置项管理。
- 外部密钥管理服务:安全要求极高时对接Vault或云KMS,让应用启动时动态拉取密钥。
- 密钥轮换:定期更新主密钥,更新后所有密文都需要重新生成。
还有一个容易被忽略的地方:日志和异常信息可能泄露密钥。Jasypt某些版本在开启debug日志后,会把加密器的参数、甚至解密后的明文打印出来。排查问题时看一眼日志没问题,但生产环境的日志级别建议保持默认或者调高,别把敏感信息写进日志文件。
5.3 性能问题与懒加载
Jasypt加解密本身有点开销,但正常来说每个加密字段只在启动阶段解密一次,对运行期性能几乎没有影响。真正要留意的是:如果把易变的短值也加密,并且每次请求都动态读取配置,性能就会变差。PooledPBEStringEncryptor可以配置poolSize,默认是1,可以根据并发情况调大一点。
jasypt: encryptor: pool-size: 8这个参数本质是加解密线程池大小。注意,Jasypt底层用的是JDK的Cipher对象,它不是完全无状态的,线程池化可以复用Cipher实例,避免反复初始化带来的开销。多实例部署时不需要把poolSize调得特别大,一般4到8就够了。
5.4ENC()里包含特殊字符的问题
如果你的密文里包含=号、+号、/号(Base64编码常见字符),ENC()包裹后直接放yaml里一般没问题,因为这些字符都在括号内部,不会被YAML解释为特殊结构。但如果某个字符串同时含有多个ENC(),比如:
some-url: http://user:ENC(abc)@host:8080/path解密时会先把ENC(abc)替换成明文,再拼接整个URL,这个场景是支持的。但是要注意,如果密文本身某个片段恰好是ENC(开头的字符,就会引发错误解析,这种属于极端情况,遇到时可以通过调整密文生成顺序或者对特殊值做整体加密规避。
5.5 项目启动后配置项为null或为密文原样
应用能启动,但业务代码里拿到的是ENC(...)原样字符串,这通常是集成没生效。排查思路:
- 确认依赖是
jasypt-spring-boot-starter,而不是漏掉starter只引入了核心库。 - 确认启动类没有显式排除自动配置。
- 如果是老项目或者自定义Spring Boot版本,需要在启动类上添加
@EnableEncryptableProperties。 - 检查日志开头有没有Jasypt自己的启动横幅,如果没有说明starter没加载。
集成了但配置项为null,一般是@Value的key与yaml里的路径不匹配,跟Jasypt无关,按Spring Boot的常规属性绑定问题排查即可。
6. 避坑指南与最佳实践:真正安全地使用配置加密
6.1 Jasypt能防什么,不能防什么
先把预期摆正。Jasypt的核心价值是防止配置文件中敏感信息被直接读取,它解决的是静态泄漏问题。比如代码仓库泄露、配置错误地出现在日志里、截图流出去。
但它不能防的是:攻击者已经拿到了运行中的JVM进程并可以dump内存的情况。因为应用运行起来之后,解密后的明文会存在于内存中,Spring容器持有这些明文字符串。如果有人能对JVM做heap dump,理论上可以提取出所有配置明文。所以:
- 服务器权限要严格管控,能登录生产环境的人是极少数。
- 不要随意在生产环境执行
jmap、jstack这类诊断命令。 - 如果威胁模型里包含内存dump攻击,那么配置加密只是其中一环,需要配合应用层别的加固。
6.2 不要把密钥放进代码库
这个问题再怎么强调都不为过。我见过有人把密钥放在application.yml里,还起了个变量名叫jasypt.encryptor.password: mySecretKey123,提交到Git仓库。加密形同虚设。
密钥的存放位置应该是:
- 开发环境:本地
.env文件,加入.gitignore;或IDE环境变量。 - 测试环境:CI/CD平台的Secret变量,或部署服务器的环境变量。
- 生产环境:专用的密钥管理服务/K8s Secret,并做访问审计。
如果密钥托管在云上,建议定期轮换,轮换时提前生成好新密文,切换时尽量做到无缝。
6.3 配置加密的覆盖面
再梳理一遍哪些配置项值得加密:
| 配置项 | 是否加密 | 理由 |
|---|---|---|
| 数据库密码 | 必须 | 最高敏感度 |
| Redis密码 | 必须 | 一般可直连内网 |
| 消息队列密码 | 必须 | 涉及业务数据传递 |
| 第三方API密钥 | 必须 | 直接关联资金/数据 |
| 内部系统Token | 建议 | 防止横向渗透 |
| 非敏感开关/阈值 | 不建议 | 加密无意义还影响可读性 |
我的原则是:能明显识别出是秘密的字段全部加密,扯不清的就加密。加密的代价很低,但泄露的代价可能极高。
6.4 推荐的最小实现配置
最后给一套可以直接抄作业的最小配置组合:
pom.xml:
<dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.5</version> </dependency>application.yml:
jasypt: encryptor: password: ${JASYPT_PASSWORD} algorithm: PBEWITHHMACSHA512ANDAES_256 iv-generator-classname: org.jasypt.iv.RandomIvGenerator启动命令:
export JASYPT_PASSWORD='你的主密钥' java -jar app.jar加解密命令:
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI \ input="明文" password="$JASYPT_PASSWORD" \ algorithm=PBEWITHHMACSHA512ANDAES_256 \ ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator这套配置下来,你的Spring Boot项目就实现了配置字段密文化、密钥环境变量化、加解密命令可复制化。日常运维中,团队谁需要新增加密字段,执行一下命令,把ENC()替换进配置即可,完全不影响开发节奏。
最后再分享一个我个人的习惯:在CI流水线里加一步校验脚本,扫描配置文件里是否有疑似明文密码的字段(比如password:后面不是ENC()开头),一旦发现就fail掉构建。这样的自动化检查往往比堆文档更有效,能从入口杜绝新的明文配置被混进来。