Spring Boot加密配置属性--Spring Cloud Vault详解

项目中敏感配置信息一般需要进行加密处理,比如数据库密码,Spring Boot内置不提供加密支持,不能加密配置文件信息,在官方文档中提供了自定义Environment和Spring Cloud Vault两种解决方案。使用jasypt-spring-boot是另一种方案。

Spring Cloud VaultHashiCorp Vault的客户端,支持访问HashiCorp Vault内存储的数据,避免了在Spring Boot程序中存储敏感数据。

本文详细介绍了如何使用jasypt-spring-boot、Spring Cloud Vault和HashiCorp Vault,如何使用Vault的AWS Secret、Database Secret、AWS EC2认证和AWS IAM认证。

自定义Environment

  1. 自己实现加解密的方法,在配置文件中使用密文,比如:
spring:
  datasource:
    password: a3Ehaf0f/S1Rt6JfOGfQ+w==
jwt:
  secret: a3Ehaf0f/S1Rt6JfOGfQ+w==
  1. 实现EnvironmentPostProcessor,在其中执行解密操作,简单示例如下:
package org.itrunner.heroes.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Map;

public class DecryptedEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Resource path = new ClassPathResource("config.yml");
        PropertySource<Map<String, Object>> propertySource = loadYaml(path);
        environment.getPropertySources().addLast(propertySource);
    }

    private PropertySource<Map<String, Object>> loadYaml(Resource path) {
        if (!path.exists()) {
            throw new IllegalArgumentException("Resource " + path + " does not exist");
        }
        try {
            OriginTrackedMapPropertySource propertySource = (OriginTrackedMapPropertySource) loader.load("custom-resource", path).get(0);
            return new DecryptedMapPropertySource(propertySource);
        } catch (IOException ex) {
            throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
        }
    }

    private static class DecryptedMapPropertySource extends MapPropertySource {
        public DecryptedMapPropertySource(OriginTrackedMapPropertySource propertySource) {
            super(propertySource.getName(), propertySource.getSource());
        }

        @Override
        public Object getProperty(String name) {
            Object value = super.getProperty(name);
            if (value instanceof CharSequence) {
                            // 执行解密,返回明文
                return "DecryptedValue";
            }
            return value;
        }
    }

}

自定义的EnvironmentPostProcessor需在META-INF/spring.factories内注册:

org.springframework.boot.env.EnvironmentPostProcessor=org.itrunner.heroes.config.DecryptedEnvironmentPostProcessor

Jasypt Spring Boot

集成jasypt-spring-boot

有三种方式集成jasypt-spring-boot:

  • 项目中如使用了@SpringBootApplication或@EnableAutoConfiguration,简单地添加jasypt-spring-boot-starter到classpath将在整个Spring环境中启用加密属性
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>
  • 添加jasypt-spring-boot到classpath,添加@EnableEncryptableProperties到main Configuration class将在整个Spring环境中启用加密属性
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot</artifactId>
    <version>2.1.0</version>
</dependency>
@Configuration
@EnableEncryptableProperties
public class MyApplication {
    ...
}
  • 添加jasypt-spring-boot到classpath,使用@EncrytablePropertySource声明加密的属性或YAML文件
@Configuration
@EncryptablePropertySource(name = "EncryptedProperties", value = "classpath:encrypted.properties")
public class MyApplication {
    ...
}

或者使用@EncryptablePropertySources:

@Configuration
@EncryptablePropertySources({@EncryptablePropertySource("classpath:encrypted.properties"),
        @EncryptablePropertySource("file:/path/to/encrypted2.properties")})
public class MyApplication {
    ....
}

加密配置

Key Required Default Value
jasypt.encryptor.password True -
jasypt.encryptor.algorithm False PBEWithMD5AndDES
jasypt.encryptor.bean False jasyptStringEncryptor
jasypt.encryptor.keyObtentionIterations False 1000
jasypt.encryptor.poolSize False 1
jasypt.encryptor.providerName False null
jasypt.encryptor.saltGeneratorClassname False org.jasypt.salt.RandomSaltGenerator
jasypt.encryptor.stringOutputType False base64
jasypt.encryptor.proxyPropertySources False false
jasypt.encryptor.property.prefix False ENC(
jasypt.encryptor.property.suffix False )

默认,加密算法为PBEWithMD5AndDES,加解密bean name为jasyptStringEncryptor,加密的数据需使用ENC()包裹。
所有这些属性都可在配置文件中声明,但加密密码不应存储在配置文件中,而应使用系统属性、命令行参数传入,只要名称为jasypt.encryptor.password即可:

java -jar jasypt-spring-boot-demo.jar --jasypt.encryptor.password=password
或
java -Djasypt.encryptor.password=password -jar jasypt-spring-boot-demo.jar

也可在application.properties 或 application.yml中使用环境变量:

jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}

配置文件示例:

spring:
  jpa:
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        default_schema: heroes
        format_sql: true
        jdbc:
          lob:
            non_contextual_creation: true
    show-sql: true
  datasource:
    platform: postgresql
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/postgres
    username: hero
    password: ENC(a3Ehaf0f/S1Rt6JfOGfQ+w==)
    initialization-mode: never
jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: 1qefhQH7mRR4LADVettR
    stringOutputType: base64
    property:
      prefix: ENC(
      suffix: )

生成加密数据

使用CLI工具JasyptPBEStringEncryptionCLI生成加密数据,如下:

java -cp jasypt-1.9.2.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="inputdata" password=secretkey algorithm=PBEWithMD5AndDES

执行后,输出如下:

----ENVIRONMENT-----------------

Runtime: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 25.191-b12 

----ARGUMENTS-------------------

algorithm: PBEWithMD5AndDES
input: hero
password: 1qefhQH7mRR4LADVettR

----OUTPUT----------------------

a3Ehaf0f/S1Rt6JfOGfQ+w==

生成后,使用ENC(密文)替换明文数据即可。

HashiCorp Vault

HashiCorp Vault提供集中管理机密(Secret)和保护敏感数据的服务,可通过UI、CLI或HTTP API访问。HashiCorp Vault使用GO语言编写。

初识HashiCorp Vault

  1. 安装HashiCorp Vault

根据您的系统下载HashiCorp Vault,然后解压zip包,其中为一可执行文件。

以linux系统为例:

$ unzip vault_1.0.2_linux_amd64.zip
$ sudo chown root:root vault
$ sudo chmod 755 vault
$ sudo mv vault /usr/local/bin/
$ vault --version

帮助
直接运行vault可查看支持的命令:

$ vault
Usage: vault <command> [args]

Common commands:
    read        Read data and retrieves secrets
    write       Write data, configuration, and secrets
    delete      Delete secrets and configuration
    list        List data or secrets
    login       Authenticate locally
    agent       Start a Vault agent
    server      Start a Vault server
    status      Print seal and HA status
    unwrap      Unwrap a wrapped secret

Other commands:
    audit          Interact with audit devices
    auth           Interact with auth methods
    kv             Interact with Vault's Key-Value storage
    lease          Interact with leases
    namespace      Interact with namespaces
    operator       Perform operator-specific tasks
    path-help      Retrieve API help for paths
    plugin         Interact with Vault plugins and catalog
    policy         Interact with policies
    secrets        Interact with secrets engines
    ssh            Initiate an SSH session
    token          Interact with tokens

运行 vault [command] [subcommand] -h可查看命令支持的参数。

path-help 查看系统、Secret引擎、认证方法等路径支持的配置,在实际应用中经常用到。比如:

$ vault path-help sys/
$ vault path-help database/
$ vault path-help database/roles
$ vault path-help aws
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值