baeldung 2024-05-11
1. 简介
Jasypt(Java Simplified Encryption)为 Spring Boot 应用程序提供了对属性源(Property Sources)进行加密的实用工具。
在本文中,我们将讨论如何添加 jasypt-spring-boot 的支持并加以使用。
2. 为什么使用 Jasypt?
当我们需要在配置文件中存储敏感信息时,实际上就等于将这些信息暴露在外——这包括各种类型的敏感数据,例如凭证信息,当然也远不止于此。
通过使用 Jasypt,我们可以对配置文件中的属性值进行加密,而应用程序则会在运行时自动解密并获取原始值。
3. 在 Spring Boot 中使用 Jasypt 的几种方式
接下来,我们讨论在 Spring Boot 中集成 Jasypt 的不同方法。
3.1 使用 jasypt-spring-boot-starter
只需在项目中添加一个依赖项:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
Maven Central 上可获取最新版本的 jasypt-spring-boot-starter。
现在,我们使用密钥 “password” 对文本 “Password@1” 进行加密,并将其添加到 encrypted.properties 文件中:
encrypted.property=ENC(uTSqb9grs1+vUv3iN8lItC0kl65lMG+8)
接着,定义一个配置类 AppConfigForJasyptStarter,将 encrypted.properties 指定为 PropertySource:
@Configuration
@PropertySource("encrypted.properties")
public class AppConfigForJasyptStarter {
}
然后,编写一个服务类 PropertyServiceForJasyptStarter,用于从 encrypted.properties 中读取值。可以通过 @Value 注解或 Environment 类的 getProperty() 方法获取解密后的值:
@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", "password");
PropertyServiceForJasyptStarter service = appCtx
.getBean(PropertyServiceForJasyptStarter.class);
assertEquals("Password@1", service.getProperty());
Environment environment = appCtx.getBean(Environment.class);
assertEquals(
"Password@1",
service.getPasswordUsingEnvironment(environment));
}
3.2 使用 jasypt-spring-boot
对于未使用 @SpringBootApplication 或 @EnableAutoConfiguration 的项目,可以直接使用 jasypt-spring-boot 依赖:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>2.0.0</version>
</dependency>
同样地,我们使用密钥 “password” 对文本 “Password@2” 进行加密,并将其添加到 encryptedv2.properties 文件中:
encryptedv2.property=ENC(dQWokHUXXFe+OqXRZYWu22BpXoRZ0Drt)
然后,为 jasypt-spring-boot 依赖创建一个新的配置类。
这里需要使用 @EncryptablePropertySource 注解:
@Configuration
@EncryptablePropertySource("encryptedv2.properties")
public class AppConfigForJasyptSimple {
}
同时,定义一个新的服务 Bean PropertyServiceForJasyptSimple 来读取 encryptedv2.properties 中的值:
@Service
public class PropertyServiceForJasyptSimple {
@Value("${encryptedv2.property}")
private String property;
public String getProperty() {
return property;
}
}
最后,通过上述服务类并设置加密所用的密钥,即可轻松获取 encryptedv2.property 的解密值:
@Test
public void whenDecryptedPasswordNeeded_GetFromService() {
System.setProperty("jasypt.encryptor.password", "password");
PropertyServiceForJasyptSimple service = appCtx
.getBean(PropertyServiceForJasyptSimple.class);
assertEquals("Password@2", service.getProperty());
}
3.3 使用自定义 Jasypt 加密器
第 3.1 节和 3.2 节中使用的加密器均采用默认配置构建。
现在,我们来定义自己的 Jasypt 加密器并在应用中使用。
自定义加密器的 Bean 定义如下:
@Bean(name = "encryptorBean")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("password");
config.setAlgorithm("PBEWithMD5AndDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
此外,我们还可以根据需要修改 SimpleStringPBEConfig 的所有属性。
同时,需要在 application.properties 中添加属性 jasypt.encryptor.bean,以便 Spring Boot 知道应使用哪个自定义加密器。
例如,我们将使用密钥 “password” 加密后的文本 “Password@3” 添加到 application.properties 中:
jasypt.encryptor.bean=encryptorBean
encryptedv3.property=ENC(askygdq8PHapYFnlX6WsTwZZOxWInq+i)
配置完成后,即可通过 Spring 的 Environment 轻松获取 encryptedv3.property 的值:
@Test
public void whenConfiguredExcryptorUsed_ReturnCustomEncryptor() {
Environment environment = appCtx.getBean(Environment.class);
assertEquals(
"Password@3",
environment.getProperty("encryptedv3.property"));
}
4. 结论
通过使用 Jasypt,我们可以为应用程序处理的数据提供额外的安全保障。
它使我们能够更专注于应用的核心逻辑,并且在需要时也可以实现自定义的加密方案。