摘要:“生产环境数据库密码泄露,连夜紧急止损!” 上周刚帮运维同事处理完一起安全事故,起因竟是新人把明文密码写进 application.yml,提交代码时忘关 gitignore。更惊心的是,事后排查发现团队 80% 的老项目都存在类似隐患 —— 要么用 Base
“生产环境数据库密码泄露,连夜紧急止损!” 上周刚帮运维同事处理完一起安全事故,起因竟是新人把明文密码写进 application.yml,提交代码时忘关 gitignore。更惊心的是,事后排查发现团队 80% 的老项目都存在类似隐患 —— 要么用 Base64 “自欺欺人”,要么密钥和密文放一起,等于给黑客留了后门。
根据 OWASP 2025 年报告,37% 的企业级应用安全漏洞源于敏感配置泄露,其中 Spring Boot 项目占比高达 62%。如果你还在把数据库密码、API 密钥明文存放,看完这篇实战指南,立刻就能堵住这个致命漏洞。
Jasypt(java Simplified Encryption)是 Spring 生态公认的配置加密工具,能无缝集成 Spring Boot3,支持多种加密算法,还能与 Nacos 等配置中心联动。相比其他方案,它有三个不可替代的优势:
3.1 环境准备与依赖配置
首先通过 Spring Initializr 创建项目,勾选 Spring Web、Spring Configuration Processor 依赖。重点在 pom.xml 添加 Jasypt starter,Spring Boot3 务必选 3.0.5 及以上版本,否则会出现自动配置类冲突:
com.github.ulisesbocchiojasypt-spring-boot-starter3.0.53.2 生成加密密文(3 种方法)
方法 1:命令行工具加密(推荐)
下载 Jasypt 1.9.3 工具包:wget https://github.com/jasypt/jasypt/archive/refs/tags/1.9.3.zip
解压后执行加密命令(以数据库密码my_db_password为例):
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="my_db_password" password="your_master_key" # 主密钥,生产环境需妥善保管algorithm="PBEWithHmacSHA512AndAES_256" # 生产级算法执行后得到类似ENC(+xQrG7eU9z8G3Lw5...)的密文,记住ENC前缀是解密标识,不可省略。
方法 2:代码生成密文(调试用)
创建工具类快速生成密文,方便开发阶段测试:
import org.jasypt.encryption.StringEncryptor;import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;public class JasyptUtils { public static String encrypt(String content, String key) { StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor; SimpleStringPBEConfig config = new SimpleStringPBEConfig; config.setPassword(key); config.setAlgorithm("PBEWithHmacSHA512AndAES_256"); encryptor.setConfig(config); return encryptor.encrypt(content); } public static void main(String args) { // 输出加密结果,记得替换为自己的密钥 System.out.println("加密后:" + encrypt("my_db_password", "your_master_key")); }}3.3 配置文件编写(YAML 示例)
将加密后的密文写入 application.yml,注意所有敏感字段都要加ENC标识:
spring: datasource: url: jdbc:mysql://localhost:3306/demo_db username: ENC(8aZ7xQ2...) # 用户名也建议加密 password: ENC(+xQrG7e...) redis: password: ENC(3kP9sR...) # Redis密码同样需要保护# Jasypt基础配置(密钥不在此配置!)jasypt: encryptor: algorithm: PBEWithHmacSHA512AndAES_256 # 与加密时保持一致 iv-generator-classname: org.jasypt.iv.RandomIvGenerator # 增强安全性3.4 注入解密密钥(生产级方案)
绝对禁止在配置文件写密钥!推荐 3 种生产环境方案:
方案 1:命令行参数注入
启动 jar 包时通过参数传递密钥:
java -Djasypt.encryptor.password=your_master_key -jar demo-app.jar方案 2:环境变量注入
先设置系统环境变量,再启动应用:
# Linux/MacOSexport JASYPT_ENCRYPTOR_PASSWORD=your_master_key# Windowsset JASYPT_ENCRYPTOR_PASSWORD=your_master_key# 启动应用java -jar demo-app.jar配置文件中可通过${JASYPT_ENCRYPTOR_PASSWORD:}自动读取环境变量。
方案 3:密钥管理服务(KMS)
大型项目推荐用阿里云 KMS、HashiCorp Vault 等工具,以阿里云为例:
在 KMS 创建密钥环和主密钥应用启动时调用 KMS API 获取解密密钥自定义StringEncryptor注入密钥:@Configurationpublic class JasyptConfig { @Bean("jasyptStringEncryptor") public StringEncryptor stringEncryptor { // 调用KMS API获取密钥,此处简化为模拟代码 String masterKey = AliKmsUtils.getSecret("jasypt-master-key"); StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor; SimpleStringPBEConfig config = new SimpleStringPBEConfig; config.setPassword(masterKey); config.setAlgorithm("PBEWithHmacSHA512AndAES_256"); encryptor.setConfig(config); return encryptor; }}3.5 验证解密效果
编写测试接口验证配置是否生效:
@RestController@RequestMapping("/test")public class ConfigTestController { @Value("${spring.datasource.password}") private String dbPassword; @GetMapping("/db-info") public String getDbInfo { // 注意:日志中绝对不能打印明文! return "数据库密码长度:" + dbPassword.length; }}启动应用访问/test/db-info,返回密码长度即表示解密成功。
错误 1:用 Base64 冒充加密
password: YWRtaW4xMjM=这种写法只是编码,随便找个 Base64 解码工具就能还原,等于裸奔。
错误 2:密钥密文放一起
# 绝对禁止!jasypt: encryptor: password: your_master_key # 密钥硬编码spring: datasource: password: ENC(xxx)拿到配置文件就能同时获取密钥和密文,加密毫无意义。
错误 3:忽视非数据库敏感字段
只加密数据库密码,却把 JWT 密钥、支付 API Key 明文存放:
# 危险写法jwt: secret: abcdef123456 # 未加密pay: alipay: appKey: 123456789 # 未加密正确做法是所有敏感字段统一用ENC加密。
错误 4:日志打印明文
// 致命错误!log.info("数据库密码:{}", dbPassword);日志会被 ELK 等系统收集,敏感信息瞬间泄露。必须脱敏:
log.info("数据库密码:{}***{}", dbPassword.substring(0,2), dbPassword.substring(dbPassword.length-2));错误 5:算法选得太弱
默认的PBEWithMD5AndDES安全性不足,生产环境必须用PBEWithHmacSHA512AndAES_256。JDK8 及以下需安装 JCE 无限强度策略文件,JDK9 + 已默认支持。
错误 6:Nacos 配置未加密
用 Nacos 做配置中心时,需在 Nacos 控制台直接存储密文,同时确保应用端 Jasypt 配置与加密时一致:
# Nacos配置示例(直接存密文)spring: datasource: password: ENC(+xQrG7e...)注意:Nacos 动态刷新时可能出现解密失败,需在@RefreshScopeBean 中重新注入配置。
错误 7:没有密钥轮换机制
密钥几年不换,一旦泄露后果严重。建议:
每 3 个月轮换一次主密钥数据库密码、API Key 同步更新用配置中心实现密钥快速切换不同环境用不同密钥,避免 “一把钥匙开所有锁”:
开发环境:用本地环境变量注入密钥测试环境:用 Jenkins 参数传递密钥生产环境:用 KMS 管理密钥配置文件通过 Profiles 区分:# application-dev.yml(开发环境)jasypt: encryptor: algorithm: PBEWithMD5AndDES # 开发环境简化算法# application-prod.yml(生产环境)jasypt: encryptor: algorithm: PBEWithHmacSHA512AndAES_256最后留个思考题:如果你的项目用了 Docker 容器化部署,Jasypt 密钥该如何安全注入?欢迎在评论区交流,点赞过千立刻出 Docker+K8s 加密实战篇!
来源:从程序员到架构师