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类。例如:
@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
引入了一项新功能来指定属性过滤器。筛选器是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