springboot 配置引數加密——jasypt
一、方法說明
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 @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開頭的名稱檢測自定義字串Encyptors1.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
和newEncryptablePropertyDetector
。
提供自定義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
引入了一項新功能來指定屬性過濾器。篩選器是EncryptablePropertyResolver
API的一部分,可讓您確定要考慮解密的屬性或屬性源。這是在甚至檢查實際屬性值以搜尋或嘗試對其進行解密之前。例如,預設情況下,所有以名稱開頭的屬性jasypt.encryptor
均不包括在內。這是為了避免在配置庫bean時在載入時產生迴圈依賴性。
DefaultPropertyFilter屬性
預設情況下,DefaultPropertyResolver
usesDefaultPropertyFilter
允許您指定以下字串模式列表:
- 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