Jasypt 为 SpringBoot 提供配置文件的加密支持
Jasypt
http://www.jasypt.org/
https://github.com/ulisesbocchio/jasypt-spring-boot
Jasypt Spring Boot 可以为 SpringBoot 程序提供配置文件的加密支持。
有三种方式可以在项目中集成 jasypt-spring-boot。
- 如果使用
@SpringBootApplication
或者@EnableAutoConfiguration
,只需要添加依赖jasypt-spring-boot-starter
,就可以在整个 Spring 环境中启用可加密属性。
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
- 添加依赖
jasypt-spring-boot-starter
,在主配置类上启用@EnableEncryptableProperties
,以在整个 Spring 环境中启用可加密属性。
<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>3.0.5</version>
</dependency>
@Configuration
@EnableEncryptableProperties
public class Application {
...
}
- 添加依赖
jasypt-spring-boot-starter
,使用@EncrytablePropertySource
声明各个可加密属性源。
可以添加多个 @EncryptablePropertySource
注解:
@Configuration
@EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties")
public class Application {
...
}
可以用来将 @EncryptablePropertySource
类型的注解分组:
```java
@Configuration
@EncryptablePropertySources({
@EncryptablePropertySource("classpath:encrypted.properties"),
@EncryptablePropertySource("classpath:encrypted2.properties")
})
public class Application {
...
}
此外,从 1.8 版本开始,@EncryptablePropertySource
支持 YAML 文件。
使用
- 选择一个加密算法,确定密钥,预先对需要加密的字符串计算加密值。
- 修改 yml 文件,配置 Jasypt 参数,替换需要加密的参数。
加密解密:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.properties.PropertyValueEncryptionUtils;
import org.jasypt.util.text.BasicTextEncryptor;
public class JasyptTest {
private static final String ALGORITHM = "PBEWithMD5AndDES";
private static final String PASSWORD = "test";
public static void main(String[] args) {
String encryption = encrypt("123456");
System.out.println(encryption);
String content = decrypt(encryption);
System.out.println(content);
System.out.println("----------------------------------");
encryptAndDecrypt("123456");
}
public static String encrypt(String content) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(ALGORITHM);
config.setPassword(PASSWORD);
encryptor.setConfig(config);
return encryptor.encrypt(content);
}
public static String decrypt(String encryption) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
config.setAlgorithm(ALGORITHM);
config.setPassword(PASSWORD);
encryptor.setConfig(config);
return encryptor.decrypt(encryption);
}
public static void encryptAndDecrypt(String content) {
// BasicTextEncryptor 内部使用的 encryptor 就是 StandardPBEStringEncryptor
// 其中指定加密算法为 PBEWithMD5AndDES
BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
basicTextEncryptor.setPassword(PASSWORD);
String encrypt1 = basicTextEncryptor.encrypt(content);
// 通过工具加密会带有前缀 ENC(, 后缀 )
String encrypt2 = PropertyValueEncryptionUtils.encrypt(content, basicTextEncryptor);
System.out.println("encrypt1 = " + encrypt1);
System.out.println(PropertyValueEncryptionUtils.isEncryptedValue(encrypt1));
System.out.println("encrypt2 = " + encrypt2);
System.out.println(PropertyValueEncryptionUtils.isEncryptedValue(encrypt2));
String decrypt1 = basicTextEncryptor.decrypt(encrypt1);
String decrypt2 = PropertyValueEncryptionUtils.decrypt(encrypt2, basicTextEncryptor);
System.out.println("decrypt1 = " + decrypt1);
System.out.println("decrypt2 = " + decrypt2);
}
}
yml 修改完善:
jasypt:
encryptor:
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
password: togest
property:
# 当算法发现配置文件中的值符合指定的前后缀时,会使用指定算法解密
# 默认值就是 ENC( 和 ),不需要配置
prefix: ENC(
suffix: )
spring:
datasource:
username: postgres
password: ENC(ruQfurPREQOwp+P2lapBXA==)
url: jdbc:postgresql://localhost:5432/...
如果不想在 yml 中指定 jasypt.encryptor.password
,可以通过命令行参数的形式传参:
java -jar xxx.jar --jasypt.encryptor.password=password
java -Djasypt.encryptor.password=password -jar xxx.jar
或者作为环境变量传递:
JASYPT_ENCRYPTOR_PASSWORD=password java -jar xxx.jar
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD:}
其他问题
Jasypt 从 3.0 后,默认使用的算法为 PBEWITHHMACSHA512ANDAES_256
,需要 JDK 9 及以上提供的 Unlimited Strength Java Cryptography Extension 支持。
如果 SpringBoot 为 1.x 版本,Jasypt 需要使用 1.x 版本。