1. 概述

在现代 Spring Boot 项目中,配置文件里难免要存放数据库密码、第三方服务密钥等敏感信息。明文存储?那等于把钥匙挂在门把手上,谁路过都能拿——踩坑预警⚠️

Jasypt(Java Simplified Encryption)是一个轻量级加密库,而 jasypt-spring-boot 是其与 Spring Boot 集成的桥梁。它允许你在 application.properties 或自定义配置文件中使用 ENC(密文) 的形式存储加密内容,运行时自动解密注入。

本文将带你一步步集成 Jasypt,涵盖主流用法和自定义加密器配置,拒绝纸上谈兵,直接上手可用

🔗 想了解 Jasypt 加密原理?可参考我们之前的 Jasypt 入门教程


2. 为什么选择 Jasypt?

安全加固:配置文件中的密码、密钥等敏感字段实现加密存储,避免泄露风险
无缝集成:Spring Boot 启动时自动解密,业务代码无感知,@Value 照样用
灵活配置:支持自定义加密算法、密钥、迭代次数等,满足合规要求
环境友好:开发、测试、生产可使用不同加密密钥,提升安全性

不适用场景:密钥本身仍需安全保管(如通过启动参数传入),不能解决密钥管理的根本问题(建议配合 Vault、KMS 等工具)


3. Jasypt 在 Spring Boot 中的三种集成方式

3.1 使用 jasypt-spring-boot-starter(推荐)

适用于标准 Spring Boot 项目(含 @SpringBootApplication 或启用自动配置)。

✅ 添加依赖

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

💡 最新版可在 Maven Central 查询

✅ 加密示例

使用命令行工具或代码加密 Password@1,密钥为 mySecretKey

# 示例命令(需下载 jasypt CLI)
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="Password@1" password=mySecretKey algorithm=PBEWithMD5AndDES

生成密文后写入 encrypted.properties

encrypted.property=ENC(uTSqb9grs1+vUv3iN8lItC0kl65lMG+8)

✅ 配置类加载加密属性

@Configuration
@PropertySource("encrypted.properties")
public class AppConfigForJasyptStarter {
}

✅ 服务类读取解密值

@Service
public class PropertyServiceForJasyptStarter {

    @Value("${encrypted.property}")
    private String property;

    public String getProperty() {
        return property;
    }

    public String getPasswordUsingEnvironment(Environment environment) {
        return environment.getProperty("encrypted.property");
    }
}

✅ 测试验证

@Test
public void whenDecryptedPasswordNeeded_GetFromService() {
    System.setProperty("jasypt.encryptor.password", "mySecretKey");
    PropertyServiceForJasyptStarter service = appCtx
      .getBean(PropertyServiceForJasyptStarter.class);
 
    assertEquals("Password@1", service.getProperty());
 
    Environment environment = appCtx.getBean(Environment.class);
 
    assertEquals(
      "Password@1", 
      service.getPasswordUsingEnvironment(environment));
}

⚠️ 密钥通过 System.setProperty 或启动参数 -Djasypt.encryptor.password=mySecretKey 传入,避免硬编码


3.2 使用 jasypt-spring-boot(非 starter 场景)

适用于未使用 @SpringBootApplication 或禁用自动配置的项目。

✅ 添加依赖

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

✅ 加密并写入配置

加密 Password@2,密钥仍为 mySecretKey

encryptedv2.property=ENC(dQWokHUXXFe+OqXRZYWu22BpXoRZ0Drt)

✅ 配置类使用 @EncryptablePropertySource

关键区别:必须使用 @EncryptablePropertySource 替代 @PropertySource

@Configuration
@EncryptablePropertySource("encryptedv2.properties")
public class AppConfigForJasyptSimple {
}

✅ 服务类读取

@Service
public class PropertyServiceForJasyptSimple {
 
    @Value("${encryptedv2.property}")
    private String property;

    public String getProperty() {
        return property;
    }
}

✅ 测试调用

@Test
public void whenDecryptedPasswordNeeded_GetFromService() {
    System.setProperty("jasypt.encryptor.password", "mySecretKey");
    PropertyServiceForJasyptSimple service = appCtx
      .getBean(PropertyServiceForJasyptSimple.class);
 
    assertEquals("Password@2", service.getProperty());
}

✅ 优势:更轻量,适合非 Boot 项目或需精细控制的场景


3.3 自定义 Jasypt 加密器(高级用法)

默认加密器使用 PBEWithMD5AndDES,强度较低。生产环境建议自定义更强算法,如 PBEWithHMACSHA512AndAES_256

✅ 定义自定义 Encryptor Bean

@Bean(name = "strongEncryptor")
public StringEncryptor stringEncryptor() {
    PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
    SimpleStringPBEConfig config = new SimpleStringPBEConfig();
    config.setPassword("myStrongKey123!");           // 密钥
    config.setAlgorithm("PBEWithHMACSHA512AndAES_256"); // 强算法
    config.setKeyObtentionIterations("10000");       // 迭代次数
    config.setPoolSize("4");                         // 线程池大小
    config.setProviderName("SunJCE");
    config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
    config.setStringOutputType("base64");
    encryptor.setConfig(config);
    return encryptor;
}

✅ 配置文件指定使用哪个 Encryptor

application.properties 中声明:

# 指定使用名为 strongEncryptor 的 Bean
jasypt.encryptor.bean=strongEncryptor

# 加密后的属性(使用上述密钥和算法加密 "Password@3")
encryptedv3.property=ENC(askygdq8PHapYFnlX6WsTwZZOxWInq+i)

✅ 测试验证

@Test
public void whenConfiguredExcryptorUsed_ReturnCustomEncryptor() {
    Environment environment = appCtx.getBean(Environment.class);
 
    assertEquals(
      "Password@3", 
      environment.getProperty("encryptedv3.property"));
}

✅ 踩坑提示:jasypt.encryptor.bean 必须与 @Bean 的 name 一致,否则会 fallback 到默认加密器


4. 总结

Jasypt 是 Spring Boot 项目中简单粗暴又实用的配置加密方案,三步搞定:

  1. 引依赖(starter 或普通版)
  2. 加密敏感值,写入 ENC(...) 格式
  3. 启动时传入密钥(-Djasypt.encryptor.password=xxx

📌 最佳实践建议

  • 密钥绝不硬编码,通过运维平台或启动参数注入
  • 生产环境使用自定义高强度加密器
  • 配合 CI/CD 实现自动化加密,避免人工操作失误

💡 完整示例代码已托管至 GitHub:https://github.com/tech-tutorial/spring-boot-jasypt-demo


原始标题:Spring Boot Configuration with Jasypt