使用过SpringBoot配置文件的朋友都知道,资源文件中的内容通常情况下是明文显示,安全性就比较低一些。打开application.properties或application.yml,比如mysql登陆密码,redis登陆密码以及第三方的密钥等等一览无余,这里介绍一个加解密组件,提高一些属性配置的安全性。

jasypt由一个国外大神写的一个springboot下的工具包。Git地址:https://github.com/ulisesbocchio/jasypt-spring-boot

直接上代码:

1、pom文件中增加依赖:

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

2、application.yml文件中增加jasypt的秘钥(该秘钥自定义的):

jasypt:
  encryptor:
    #加密秘钥
    password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7

3、测试类:

SpringBoot配置文件敏感信息加密-jasypt_自定义
@RestController
public class IndexController {

    @Autowired
    private StringEncryptor encryptor;

    /**
     * 测试jasypt加密解密
     */
    @GetMapping("/jasypt")
    public void testJasypt() {
        String password = "123456";
        String encryptPwd = encryptor.encrypt(password);
        System.out.println("加密::" + encryptPwd);
        System.out.println("解密:" + encryptor.decrypt(encryptPwd));
    }

}
SpringBoot配置文件敏感信息加密-jasypt_自定义

4、启动服务,在控制台可以看到jaspyt的默认配置(比如加密方式是PBEWithMD5AndDES):

SpringBoot配置文件敏感信息加密-jasypt_spring_03

5、在浏览器请求(端口号自定义):http://localhost:18081/jasypt ,在控制台打印信息:

加密: stqvirrvG8TcLz9mqflBDQ==
解密:123456

jasypt由于其使用的是PBEWithMD5AndDES加密方式,所以每次加密出来的结果都不一样,但是解密都是一样的,所以很适合对数据进行加密

6、将加密的结果替换配置文件中的敏感字段(这里以数据库密码为例,数据库密码是123456):

SpringBoot配置文件敏感信息加密-jasypt_自定义
spring:
  application:
    name: service-provider
  datasource: 
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/mydb?autoReconnect=true&failOverReadOnly=false&createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=utf8
    username: root
    password: ENC(stqvirrvG8TcLz9mqflBDQ==)
SpringBoot配置文件敏感信息加密-jasypt_自定义

上面的 ENC()是固定写法,()里面是加密后的信息。

7、在测试类中增加代码:

SpringBoot配置文件敏感信息加密-jasypt_自定义
    @Value("${spring.datasource.password}")
    private String dbPassword; // 数据库密码

    /**
     * 测试配置文件字段加密后,项目中该字段的值
     */
    @GetMapping("/password")
    public String password() {
        return dbPassword;
    } 
SpringBoot配置文件敏感信息加密-jasypt_自定义

请求http://localhost:18081/password,会发现结果是123456,说明直接将加密文件解密出来了

 

扩展

a、自定义上面第6点中ENC()的固定写法。在配置文件中增加jasypt.encryptor.property:

SpringBoot配置文件敏感信息加密-jasypt_自定义
jasypt:
  encryptor:
    #加解密秘钥
    password: EbfYkitulv73I2p0mXI50JMXoaxZTKJ7
    #设置前缀后缀
    property:
      prefix: "ENC@["
      suffix: "]"
    
SpringBoot配置文件敏感信息加密-jasypt_自定义

b、将加解密秘钥放在配置文件中是不安全的,有如下几种解决办法:

1、在启动类上赋值秘钥:

SpringBoot配置文件敏感信息加密-jasypt_自定义
@SpringBootApplication
public class ProviderApplication {

    public static void main(String[] args) {
        /** 配置加解密秘钥,与配置文件的密文分开放 */
        System.setProperty("jasypt.encryptor.password", "travel-app");
//        System.setProperty("jasypt.encryptor.password", "EbfYkitulv73I2p0mXI50JMXoaxZTKJ7");

        SpringApplication.run(ProviderApplication.class, args);
    }

}
SpringBoot配置文件敏感信息加密-jasypt_自定义

2、自定义StringEncryptor:

SpringBoot配置文件敏感信息加密-jasypt_自定义
/**
     * 配置StringEncryptor
     */
    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("EbfYkitulv73I2p0mXI50JMXoaxZTKJ7");
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.salt.NoOpIVGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }
SpringBoot配置文件敏感信息加密-jasypt_自定义

3、使用jar的方式启动

 

 

踩过的坑

a、必须配置加解密用的秘钥,即jasypt.encryptor.password,不然启动会报错

b、springboot2.x以下的版本,只能用jasypt1.x的版本。如果用jasypt2.x的版本,启动会报错,详见https://github.com/ulisesbocchio/jasypt-spring-boot/issues/97