SpringCloud实现自定义environment中的value加密

environment中的value为什么要加密?

未经过加密的配置文件,密码均是采用明文密码,很容易导致信息泄露。

SpringCloud environment中的value加密代码如下


package com.xxx.core.encryption;

import com.xxx.util.encrypt.AesUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.Map;

/**
 * @author xxx
 * @date 2022/10/30
 */
@Slf4j
public class EnableEncryptionData implements BeanFactoryPostProcessor, Ordered {

    private final ConfigurableEnvironment environment;
	
	//根据自己需求自定义
    private static final String PREFIX = "ENC(";

    private static final String SUFFIX = ")";

    /**
     * 扫描自定义配置的文件
     */
    private static final String BOOTSTRAP_CONFIGURE = "bootstrap";

    public EnableEncryptionData(ConfigurableEnvironment environment) {
        this.environment = environment;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        MutablePropertySources propertySources = environment.getPropertySources();
        for (PropertySource<?> propertySource : propertySources) {
            String name = propertySource.getName();
            if (!name.startsWith(BOOTSTRAP_CONFIGURE)){
                continue;
            }

            Object object = propertySource.getSource();
            if (object instanceof Map){
                Map<String, Object> source = (Map<String, Object>) propertySource.getSource();
                source.forEach((k, v) -> {
                    if (v instanceof String){
                        String valueEncryptionStr = (String) v;
                        if (!StringUtils.isEmpty(valueEncryptionStr) && valueEncryptionStr.startsWith(PREFIX) && valueEncryptionStr.endsWith(SUFFIX)){
                            try {
                                valueEncryptionStr = getEncryptionStr(valueEncryptionStr);
                                //根据自己需求自定义解密算吗
                                valueEncryptionStr = AesUtils.decodeStr(valueEncryptionStr, AesUtils.P_KEY);
                                source.put(k, valueEncryptionStr);
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }
                });
            }
        }
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE - 100;
    }

    /**
     * 获取加密后的信息
     * @param encryptionStr
     * @return
     */
    private static String getEncryptionStr(String encryptionStr){
        encryptionStr = encryptionStr.substring(PREFIX.length());
        encryptionStr = encryptionStr.substring(0, encryptionStr.length()-SUFFIX.length());
        return encryptionStr;
    }
}

springboot 配置Configuration

package com.xxx.core.encryption;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;

/**
 * @author HanKeQi
 * @date 2022/10/30
 */
@Configuration
public class EnvironmentConfig {

    @Bean
    public static EnableEncryptionData enableEncryptionData(final ConfigurableEnvironment environment) {

        return new EnableEncryptionData(environment);
    }
}

Aes加密代码

package com.xxx.util.encrypt;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;

/**
 * @author HanKeQi
 * @date 2022/10/30
 */
@Slf4j
public class AesUtils {

    public static final String IV = "vKapxbKpyptKkwuP";

    private static final String P_KCS5_PADDING="AES/CBC/PKCS5Padding";

    private static final String KEY = "AES";

    public static final String P_KEY = "6U7Si019ireqa7vAscWBkbPClOYtn6gb";


    /**
     * @param content base64处理过的字符串
     * @param pkey    密匙
     * @return String    返回类型
     * @throws Exception
     * @throws
     * @Title: aesDecodeStr
     * @Description: 解密 失败将返回NULL
     */
    public static String decodeStr(String content, String pkey) throws Exception {
        try {
            log.info("待解密内容: {}", content);
            byte[] base64DecodeStr = Base64.decodeBase64(content);
            byte[] aesDecode = decode(base64DecodeStr, pkey);
            if (aesDecode == null) {
                return null;
            }
            String result;
            result = new String(aesDecode, "UTF-8");
            return result;
        } catch (Exception e) {
            throw new Exception("解密异常");
        }
    }
    /**
     * 解密 128位
     *
     * @param content 解密前的byte数组
     * @param pkey    密匙
     * @return result  解密后的byte数组
     * @throws Exception
     */
    public static byte[] decode(byte[] content, String pkey,String IV) throws Exception {

        SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(),  KEY);
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
        //创建密码器
        Cipher cipher = Cipher.getInstance(P_KCS5_PADDING);
        //初始化解密器
        cipher.init(Cipher.DECRYPT_MODE, skey, iv);
        byte[] result = cipher.doFinal(content);
        // 解密
        return result;
    }

    public static byte[] decode(byte[] content, String pkey) throws Exception {
        return decode(content,pkey,IV);
    }

    /**
     * @param content 加密前原内容
     * @param pkey    长度为16个字符,128位
     * @return base64EncodeStr   aes加密完成后内容
     * @throws
     * @Title: aesEncryptStr
     * @Description: aes对称加密
     */
    public static String encryptStr(String content, String pkey) {
        byte[] aesEncrypt = encrypt(content, pkey);
        String base64EncodeStr = Base64.encodeBase64String(aesEncrypt);
        return base64EncodeStr;
    }


    /**
     * 加密 128位
     *
     * @param content 需要加密的原内容
     * @param pkey    密匙
     * @return
     */
    public static byte[] encrypt(String content, String pkey, String iv) {
        try {
            //SecretKey secretKey = generateKey(pkey);
            //byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(), KEY);
            Cipher cipher = Cipher.getInstance(P_KCS5_PADDING);// "算法/加密/填充"
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skey, ivParameterSpec);//初始化加密器
            byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
            return encrypted; // 加密
        } catch (Exception e) {
            log.info("encrypt() method error:", e);
        }
        return null;
    }
    public static byte[] encrypt(String content, String pkey) {
        return encrypt(content,pkey, IV);
    }


}

配置文件

spring:
  redis:
    database: 1
    host: redis.commons.svc.cluster.local
    port: 6379
    # 使用了 AesUtils.encryptStr("ADoZH2Gw6KEw51c3Mk", P_KEY);
    password: ENC(hji+7pHQpX0f0/dVncyT/leJ6sWHiCUlFq7LdDJjo1s=)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值