springboot 配置参数加密——jasypt

Posted 书梦一生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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使用的自定义包装的实现PropertySourceEnumerablePropertySourceMapPropertySourcetrue为此属性指定时,拦截机制将在每个特定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(); }

提供自定义加密属性,prefixsuffix

如果您要做的就是为加密属性使用不同的前缀/后缀,则可以继续使用所有默认实现,而只需在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




以上是关于springboot 配置参数加密——jasypt的主要内容,如果未能解决你的问题,请参考以下文章

springboot-接口安全设计

springboot-接口安全设计

Springboot之接口简单加密和验证

SpringBoot配置文件敏感信息加密

SpringBoot 配置文件这样加密,才足够安全!

SpringBoot配置文件中的数据加密