一、方法說明
Jasypt Spring Boot為Spring Boot應用程序中的屬性源提供了加密支持。
有3種方式集成jasypt-spring-boot到您的項目中:
jasypt-spring-boot-starter如果使用@SpringBootApplication或@EnableAutoConfiguration將在整個Spring Environment中啟用可加密的屬性,只需將starter jar添加到您的類路徑中- 添加
jasypt-spring-boot到類路徑並添加@EnableEncryptableProperties到主Configuration類,以在整個Spring環境中啟用可加密屬性 - 添加
jasypt-spring-boot到您的類路徑並聲明單個可加密屬性源@EncrytablePropertySource
1、如果您的Spring Boot應用程序使用@SpringBootApplication或@EnableAutoConfiguration且可加密屬性將在整個Spring Environment中啟用,則只需將starter jar依賴項添加到您的項目中(這意味着任何系統屬性,環境屬性,命令行參數,application.properties,yaml屬性以及任何其他自定義屬性源可以包含加密屬性):
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2、如果您不使用@SpringBootApplication或@EnableAutoConfiguration自動配置批注,則將此依賴項添加到您的項目中:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>3.0.3</version>
</dependency>
然后添加@EnableEncryptableProperties到您的Configuration類。例如:
@Configuration
@EnableEncryptableProperties
public class MyApplication {
...
}
並且可加密屬性將在整個Spring環境中啟用(這意味着任何系統屬性,環境屬性,命令行參數,application.properties,yaml屬性以及任何其他自定義屬性源都可以包含加密屬性)
3、如果您不使用@SpringBootApplication或@EnableAutoConfiguration自動配置批注,並且不想在整個Spring Environment中啟用可加密屬性,則還有第三個選項。首先將以下依賴項添加到您的項目中:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>3.0.3</version>
</dependency>
然后@EncryptablePropertySource在配置文件中添加所需數量的注釋。就像您使用Spring的@PropertySource注釋一樣。例如:
@Configuration
@EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties")
public class MyApplication {
...
}
方便地,還有一種@EncryptablePropertySources注釋可以用來對如下類型的注釋進行分組@EncryptablePropertySource:
@Configuration
@EncryptablePropertySources({@EncryptablePropertySource("classpath:encrypted.properties"),
@EncryptablePropertySource("classpath:encrypted2.properties")})
public class MyApplication {
...
}
二、基於密碼的加密配置
Jasypt使用StringEncryptor解密屬性。對於所有這三種方法,如果在Spring Context中未找到自定義項StringEncryptor(有關詳細信息,請參見“自定義加密器”部分),則會自動創建一個可通過以下屬性(系統,屬性文件,命令行參數,環境變量等)進行配置的方法。 ):
| 鍵 | 需要 | 默認值 |
| jasypt.encryptor.password | 真正 | -- |
| jasypt.encryptor.algorithm | 假 | PBEWITHHMACSHA512ANDAES_256 |
| jasypt.encryptor.key-obtention-iterations | 假 | 1000 |
| jasypt.encryptor.pool-size | 假 | 1個 |
| jasypt.encryptor.provider-name | 假 | SunJCE |
| jasypt.encryptor.provider-class-name | 假 | 空值 |
| jasypt.encryptor.salt-generator-classname | 假 | org.jasypt.salt.RandomSaltGenerator |
| jasypt.encryptor.iv-generator-classname | 假 | org.jasypt.iv.RandomIvGenerator |
| jasypt.encryptor.string-output-type | 假 | base64 |
| jasypt.encryptor.proxy-property-sources | 假 | 假 |
| jasypt.encryptor.skip-property-sources | 假 | 空清單 |
唯一需要的屬性是加密密碼,其余的可以保留為使用默認值。雖然所有這些特性可以在屬性文件中聲明,加密密碼不應該被存放在一個屬性文件,它應該是為系統屬性,命令行參數或環境變量傳遞並盡可能它的名字是jasypt.encryptor.password它會工作。
最后一個屬性jasypt.encryptor.proxyPropertySources用於指示jasyp-spring-boot如何截取屬性值以進行解密。默認值,false使用的自定義包裝的實現PropertySource,EnumerablePropertySource和MapPropertySource。當true為此屬性指定時,攔截機制將在每個特定PropertySource實現上使用CGLib代理。在某些PropertySource必須保留原件類型的情況下,這可能很有用。
三、使用您自己的自定義加密器
對於加密器的自定義配置和加密器密碼的來源,您始終可以在Spring Context中定義自己的StringEncryptor bean,並且默認的加密器將被忽略。例如:
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword("password");
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
請注意,bean名稱是必需的,因為jasypt-spring-boot按version開頭的名稱檢測自定義字符串Encyptors 1.5。缺省的bean名稱是:
jasyptStringEncryptor
但也可以通過定義屬性來覆蓋此屬性:
jasypt.encryptor.bean
因此,例如,如果定義,jasypt.encryptor.bean=encryptorBean則可以使用該名稱定義自定義加密器:
@Bean("encryptorBean")
public StringEncryptor stringEncryptor() {
...
}
四、自定義屬性檢測器,前綴,后綴和/或解析器
截至jasypt-spring-boot-1.10目前,已有新的擴展點。EncryptablePropertySource現在用於EncryptablePropertyResolver解析所有屬性:
public interface EncryptablePropertyResolver {
String resolvePropertyValue(String value);
}
此接口的實現負責檢測和解密屬性。默認實現DefaultPropertyResolver使用前述 StringEncryptor和new EncryptablePropertyDetector。
提供自定義 EncryptablePropertyDetector
您可以通過提供EncryptablePropertyDetector帶有名稱的類型的Bean來覆蓋默認實現,encryptablePropertyDetector或者如果您想提供自己的Bean名稱,覆蓋屬性jasypt.encryptor.property.detector-bean並指定您想要給Bean的名稱,則可以覆蓋默認實現。提供此功能時,您將負責檢測加密的屬性。例:
private static class MyEncryptablePropertyDetector implements EncryptablePropertyDetector {
@Override
public boolean isEncrypted(String value) {
if (value != null) {
return value.startsWith("ENC@");
}
return false;
}
@Override
public String unwrapEncryptedValue(String value) {
return value.substring("ENC@".length());
}
}
@Bean(name = "encryptablePropertyDetector")
public EncryptablePropertyDetector encryptablePropertyDetector() {
return new MyEncryptablePropertyDetector();
}
提供自定義加密屬性,prefix並suffix
如果您要做的就是為加密屬性使用不同的前綴/后綴,則可以繼續使用所有默認實現,而只需在application.properties(或application.yml)中覆蓋以下屬性:
jasypt: encryptor: property: prefix: "ENC@[" suffix: "]"
提供自定義 EncryptablePropertyResolver
您可以通過提供EncryptablePropertyResolver帶有名稱的類型的Bean來覆蓋默認實現,encryptablePropertyResolver或者如果您想提供自己的Bean名稱,覆蓋屬性jasypt.encryptor.property.resolver-bean並指定您想要給Bean的名稱,則可以覆蓋默認實現。提供此功能時,您將負責檢測和解密加密的屬性。例:
class MyEncryptablePropertyResolver implements EncryptablePropertyResolver {
private final PooledPBEStringEncryptor encryptor;
public MyEncryptablePropertyResolver(char[] password) {
this.encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPasswordCharArray(password);
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
config.setKeyObtentionIterations("1000");
config.setPoolSize(1);
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
}
@Override
public String resolvePropertyValue(String value) {
if (value != null && value.startsWith("{cipher}")) {
return encryptor.decrypt(value.substring("{cipher}".length()));
}
return value;
}
}
@Bean(name="encryptablePropertyResolver")
EncryptablePropertyResolver encryptablePropertyResolver(@Value("${jasypt.encryptor.password}") String password) {
return new MyEncryptablePropertyResolver(password.toCharArray());
}
請注意,通過覆蓋EncryptablePropertyResolver,您可能對前綴,后綴具有任何其他配置或替代, EncryptablePropertyDetector並且它們StringEncryptor將停止工作,因為默認解析器使用它們。您必須自己連接所有這些東西。幸運的是,在大多數情況下,您不必重寫此bean,前面的選項就足夠了。
但是如您在實施中所見,加密屬性的檢測和解密是內部的 MyEncryptablePropertyResolve
四、使用過濾器
jasypt-spring-boot:2.1.0引入了一項新功能來指定屬性過濾器。篩選器是EncryptablePropertyResolverAPI的一部分,可讓您確定要考慮解密的屬性或屬性源。這是在甚至檢查實際屬性值以搜索或嘗試對其進行解密之前。例如,默認情況下,所有以名稱開頭的屬性jasypt.encryptor 均不包括在內。這是為了避免在配置庫bean時在加載時產生循環依賴性。
DefaultPropertyFilter屬性
默認情況下,DefaultPropertyResolverusesDefaultPropertyFilter允許您指定以下字符串模式列表:
- jasypt.encryptor.property.filter.include-sources:指定要包括在解密中的屬性源名稱模式
- jasypt.encryptor.property.filter.exclude-sources:指定要排除以解密的屬性源名稱模式
- jasypt.encryptor.property.filter.include-names:指定要包括在解密中的屬性名稱模式
- jasypt.encryptor.property.filter.exclude-names:指定要排除用於解密的屬性名稱模式
提供自定義 EncryptablePropertyFilter
您可以通過提供EncryptablePropertyFilter帶有名稱的類型的Bean來覆蓋默認實現,encryptablePropertyFilter或者如果您想提供自己的Bean名稱,覆蓋屬性jasypt.encryptor.property.filter-bean並指定您想要給Bean的名稱,則可以覆蓋默認實現。提供此功能時,您將負責檢測要考慮解密的屬性和/或屬性源。例:
class MyEncryptablePropertyFilter implements EncryptablePropertyFilter {
public boolean shouldInclude(PropertySource<?> source, String name) {
return name.startsWith('encrypted.');
}
}
@Bean(name="encryptablePropertyFilter")
EncryptablePropertyFilter encryptablePropertyFilter() {
return new MyEncryptablePropertyFilter();
}
EncryptablePropertyResolver
而應使用默認的解析器。如果提供自定義解析器,則您將負責檢測和解密屬性的整個過程。
參考鏈接
git鏈接jasypt-spring-boot:https://github.com/ulisesbocchio/jasypt-spring-boot
