jasypt对配置信息进行加密

在项目中一般会将数据库,Redis等一些连接配置信息放在Properties(属性配置)文件中,Spring配置文件中通过context:property-placeholder 引入,需要属性的地方使用${属性key}的方式。在SpringBoot项目中,这些配置信息则在yml文件中。出于安全的考虑,一般会将这些信息进行加密

其实加密的思路就是:自定义加密规则,加密明文得到密文,使用密文替换明文,继承placeholder,在自定义的placeholder中进行解密,Spring配置文件使用自定义的placeholder引入配置文件。这些操作完全可以自己去实现而不用借助第三方,但是使用jasypt更加简化这些步骤

jasypt我这里采用PBEWithMD5AndDES加密方法,每次运行得到的密文都是不一样的,但是可以通过这些密文解密得到唯一的明文,这种加密方法也属于可逆加密的一种,也只有可逆加密方法才适合对配置信息进行加密,毕竟涉及到加密和解密双向操作

jasypt与Spring整合

引入依赖

<dependency>
      <groupId>org.jasypt</groupId>
      <artifactId>jasypt</artifactId>
      <version>1.9.3</version>
</dependency>
<dependency>
      <groupId>org.jasypt</groupId>
      <artifactId>jasypt-spring31</artifactId>
      <version>1.9.3</version>
</dependency>

加密明文得到密文

直接通过jasypt的api进行加密

public static void main(String[] args) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        // 设置密钥
        config.setPassword("password");
        // 设置加密方法
        config.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setConfig(config);
        // 加密
        String encryptStr = encryptor.encrypt("123456");
        System.out.println(encryptStr);
        // 解密
        // System.out.println(encryptor.decrypt(encryptStr));
    }

加密和解密必须使用同一个密钥

通过一个main方法直接得到需要的密文,接下来在属性文件中进行替换

使用密文替换明文

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///maven
jdbc.user=root
jdbc.password=ENC(/a2d+QFXZXOl79sTxozVEw==)

这里只针对password进行加密,实际上所有的属性都可以加密,但是必须使用ENC(密文)的格式,这是jasypt规定的

配置jasypt

配置jasypt有两种方式:通过XML,通过配置类。

XML方式

<!--配置加密方式及密钥-->
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
    <!--加密方式-->
    <property name="algorithm" value="PBEWithMD5AndDES"/>
    <!--密钥-->
    <property name="password" value="MYPASSWORD"/>
</bean>
<!--配置加密器,将用于解密-->
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
    <property name="config" ref="environmentVariablesConfiguration"/>
</bean>
<!-- 使用EncryptablePropertyPlaceholderConfigurer引入属性文件 不再使用context:property-placeholder-->
<bean id="placeholderConfig" class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
    <constructor-arg ref="configurationEncryptor"/>
    <property name="locations">
        <list>
            <!--根据实际情况替换成项目属性文件位置-->
            <value>classpath:/properties/jdbc.properties</value>
            <value>file:D://properties//jdbc.properties</value>
        </list>
    </property>
</bean>

配置类方式

package com.config;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;

@Configuration
public class EncryPropertiesConfig {

    /**
     * 配置加密方式及密钥
     * @return
     */
    @Bean
    public EnvironmentStringPBEConfig getEnvironmentStringPBEConfig() {
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        // 设置加密方式
        config.setAlgorithm("PBEWithMD5AndDES");
        // 设置密钥
        config.setPassword("MYPASSWORD");
        return config;
    }

    /**
     * 配置加密器,将用于解密
     * @return
     */
    @Bean
    public StandardPBEStringEncryptor getStandardPBEStringEncryptor() {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setConfig(getEnvironmentStringPBEConfig());
        return encryptor;
    }

    /**
     * 引入属性文件
     * @return
     */
    @Bean
    public EncryptablePropertyPlaceholderConfigurer getEncryptablePropertyPlaceholderConfigurer() {
        EncryptablePropertyPlaceholderConfigurer placeholderConfigurer = new EncryptablePropertyPlaceholderConfigurer(getStandardPBEStringEncryptor());
        placeholderConfigurer.setLocation(new ClassPathResource("/properties/jdbc.properties"));
        placeholderConfigurer.setLocation(new FileSystemResource("D://properties//jdbc.properties"));
        return placeholderConfigurer;
    }


}

将这个配置所在的包配置在context:component-scan扫描范围下,这样就可以了

<context:component-scan base-package="com.lynu;com.config"></context:component-scan>

jasypt与SpringBoot整合

引入依赖

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

加密明文得到密文

同Spring整合的方法一样,写一个main方法调用jasypt的api,这里不在复述

使用密文替换明文

  # 数据源配置
  datasource:
    url: jdbc:mysql:///maven
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: ENC(/a2d+QFXZXOl79sTxozVEw==)

这里同样需要使用ENC(密文)的格式

配置jasypt

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    password: MYPASSWORD

其他加密方案

Spring中使用jasypt,实际上就是替换placeholder进行的,如果项目中的某些配置,没有使用 placeholder + ${} 的方法,又该如何配置呢?

  1. 自定义加解密方法
  2. 加密明文得到密文,使用密文替换,只不过不用ENC()的格式了,因为是我们自定义的方案
  3. 将XML中的配置改为Java类的配置方法,在配置类中解密

我实现过QuartzLogback的,二者都有操作数据库的连接信息(Quartz将定时配置在数据库,Logback往数据库中insert日志)

Quartz参考的是 【Quartz】解密properties配置文件中的账号密码

Logback我通过继承DataSourceConnectionSource,重写方法getConnection()方法,在这个方法中对密码进行解密

更多jasypt加密方法与使用技巧,可以参考jasypt官网 以及 jasypt-spring-boot的github地址

posted @ 2020-07-11 12:29  OverZeal  阅读(2160)  评论(0编辑  收藏  举报