使用jasypt对springboot项目 解密properties 配置文件加密

1.引入配置文件

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

方式一:

2.启动类添加注解(创建了配置文件可以不添加注解)

@EnableEncryptableProperties
@SpringBootApplication
@EnableFeignClients(basePackages= {"com.mybatis.plus.web.client"})
@EnableHystrix
@EnableScheduling
@EnableEncryptableProperties
public class PlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(PlusApplication.class, args);
    }

}

3.添加配置文件

package com.mybatis.plus.config.enc;

import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyDetector;
import org.springframework.stereotype.Component;

@Component("encryptablePropertyDetector")
public class Base64EncryptablePropertyDetector implements EncryptablePropertyDetector {
    private static final String PREFIX = "password:";

    @Override
    public boolean isEncrypted(String property) {
        if (property == null) {
            return false;
        }
        return property.startsWith(PREFIX);
    }

    @Override
    public String unwrapEncryptedValue(String property) {
        return property.substring(PREFIX.length());
    }
}

 

package com.mybatis.plus.config.enc;

import cn.hutool.core.lang.Console;
import com.mybatis.plus.utils.DesUtil;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;

@Component("encryptablePropertyResolver")
public class Base64EncryptablePropertyResolver implements EncryptablePropertyResolver {
    @Autowired
    private Base64EncryptablePropertyDetector encryptablePropertyDetector;

    @Override
    public String resolvePropertyValue(String value) {
        return Optional.ofNullable(value)
            .filter(encryptablePropertyDetector::isEncrypted)
            .map(resolveValue -> {
                final String unwrapEncryptedValue = encryptablePropertyDetector.unwrapEncryptedValue(resolveValue);
//                return new String(Base64.getDecoder().decode(unwrapEncryptedValue),
//                    StandardCharsets.UTF_8);
                return DesUtil.decrypt(unwrapEncryptedValue);
            })
            .orElse(value);
    }

    public static void main(String[] args) {
        String encodeToString = Base64.getEncoder().encodeToString(new String("XM_zm2019").getBytes());
        String s = new String(Base64.getDecoder().decode(encodeToString),
                StandardCharsets.UTF_8);
        Console.log(s);
        Console.log(encodeToString);
    }
}

工具类:

package com.mybatis.plus.utils;


import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;

/**
 * DES常用解密加密工具类
 */
public class DesUtil {

    public static void main(String[] args) throws Exception {
        long temp = System.currentTimeMillis();
        //加密字符串
        System.out.println("生成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "");
        String message = "XM_zm2019";
        System.out.println("原文:" + message);
        temp = System.currentTimeMillis();
        String messageEn = encrypt(message);
        System.out.println("密文:" + messageEn);
        System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "");
        temp = System.currentTimeMillis();
        String messageDe = decrypt(messageEn);
        System.out.println("解密:" + messageDe);
        System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "");
    }

    //默认的字符编码
    private static final String DEFAULT_CHARSET = "utf-8";

    //秘钥字符串
    private static final String PASSWORD = "iJavanGe!@#+xMSzmigyx51JmN==";

    //算法
    private static final String ALGORITHM = "DES";

    /**
     * 解密DES
     * @param datasource 需要加密的内容
     * @return 解密后的明文 数据
     */
    public static String decrypt(String datasource){
        try{
            // 创建一个DESKeySpec对象,PASSWORD可任意指定
            DESKeySpec desKey = new DESKeySpec(PASSWORD.getBytes());
            // 创建一个密匙工厂
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            // 生成密钥
            SecretKey secretkey = keyFactory.generateSecret(desKey);
            // 指定获取DES的Cipher对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, secretkey, new SecureRandom());
            // 真正开始解密操作
            return new String(cipher.doFinal(parseHexStr2Byte(datasource)));
        }catch(Throwable e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加密32位
     * @param datasource 需要加密的内容
     * @return 加密的内容
     */
    public static String encrypt(String datasource) {
        try{
            DESKeySpec desKey = new DESKeySpec(PASSWORD.getBytes());
            //创建一个密匙工厂,获取secretKey
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            SecretKey secretKey = keyFactory.generateSecret(desKey);
            //指定获取DES的Cipher对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
            //数据加密
            return parseByte2HexStr(cipher.doFinal(datasource.getBytes(DEFAULT_CHARSET)));
        }catch(Throwable e){
            e.printStackTrace();
        }
        return null;
    }


    public static String parseByte2HexStr(byte[] buf) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; ++i) {
            String hex = Integer.toHexString(buf[i] & 255);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    private static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        } else {
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; ++i) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }

}

 

使用:

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/zongmu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
    username: root
    password: password:DB83AB023F35081C936DA71860F6EB63

 

方式二: 实现  StringEncryptor  接口 此方式不用启动类添加注解 但是只能使用ENC(XXX)的加密格式

1.添加配置文件

package com.mybatis.plus.config.enc;

import com.mybatis.plus.utils.DesUtil;
import org.apache.commons.lang3.StringUtils;
import org.jasypt.encryption.StringEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component("desencrypt")
public class NrStringEncryptor implements StringEncryptor {
    private static Logger logger = LoggerFactory.getLogger(NrStringEncryptor.class);


    @Override
    public String encrypt(String message) {
        if (StringUtils.isNotBlank(message)){
            try {
//                logger.info("加密前密码:"+message);
                message = DesUtil.encrypt(message);
                logger.info("加密后密码:"+message);
                logger.info("配置信息加密成功!");
            } catch (Exception e) {
                logger.error("服务运行中:配置秘钥信息加密失败!");
            }
        }
        return message;
    }

    @Override
    public String decrypt(String encryptedMessage) {
        if (StringUtils.isNotBlank(encryptedMessage)){
            try {
                logger.info("解密前密码:"+encryptedMessage);
                encryptedMessage = DesUtil.decrypt(encryptedMessage);
//                logger.info("解密后密码:"+encryptedMessage);
                logger.info("配置信息解密成功!");
            } catch (Exception e) {
                logger.error("服务启动中:配置秘钥信息解密失败,请检查配置是否正确!");
            }
        }
        return encryptedMessage;
    }
}

 工具类同方式一

 

2.yml中增加配置

jasypt:
  encryptor:
    bean: desencrypt

 

3.使用示例

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/zongmu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
    username: root
    password: ENC(DB83AB023F35081C936DA71860F6EB63)

 

posted @ 2022-12-02 14:32  官萧何  阅读(886)  评论(0编辑  收藏  举报