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地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM