SpringBoot实现自定义environment中的value加密
environment中的value为什么要加密?
未经过加密的配置文件,密码均是采用明文密码,很容易导致信息泄露。
SpringBoot environment中的value加密代码如下
package com.xxx.core.encryption;import com.google.common.collect.Maps;
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.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.origin.OriginTrackedValue;
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 HanKeQi* @date 2023/9/4*/
@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;}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {MutablePropertySources propertySources = environment.getPropertySources();for (PropertySource<?> propertySource: propertySources){if (propertySource instanceof OriginTrackedMapPropertySource){OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource;String activeName = originTrackedMapPropertySource.getName();Map<String, Object> activeSource = (Map<String, Object>)propertySources.get(activeName).getSource();Map<String, Object> newConfigMap = Maps.newHashMap();activeSource.forEach((k,v)->{if (v instanceof OriginTrackedValue){Object valueObj = ((OriginTrackedValue) v).getValue();if (valueObj instanceof String){String valueEncryptionStr = (String) valueObj;if (!StringUtils.isEmpty(valueEncryptionStr) && valueEncryptionStr.startsWith(PREFIX) && valueEncryptionStr.endsWith(SUFFIX)){try {valueEncryptionStr = getEncryptionStr(valueEncryptionStr);valueEncryptionStr = AesUtils.decodeStr(valueEncryptionStr, AesUtils.P_KEY);newConfigMap.put(k, valueEncryptionStr);return;}catch (Exception e){e.printStackTrace();}}}}newConfigMap.put(k, v);});propertySources.replace(activeName, new OriginTrackedMapPropertySource(activeName , newConfigMap, true));}}}@Overridepublic 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 {@Beanpublic 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: 1host: redis.commons.svc.cluster.localport: 6379# 使用了 AesUtils.encryptStr("ADoZH2Gw6KEw51c3Mk", P_KEY);password: ENC(hji+7pHQpX0f0/dVncyT/leJ6sWHiCUlFq7LdDJjo1s=)
相关文章:
SpringBoot实现自定义environment中的value加密
environment中的value为什么要加密? 未经过加密的配置文件,密码均是采用明文密码,很容易导致信息泄露。 SpringBoot environment中的value加密代码如下 package com.xxx.core.encryption;import com.google.common.collect.Maps; import lomb…...
celery的用法--任务调度
在Celery中,任务(Task)是执行特定操作的基本单元。任务可以异步执行,可以带有参数,可以返回结果,可以链式调用,还可以设置任务优先级、超时等属性。 1.定义任务: 使用app.task装饰器…...
MyBatis-Plus学习笔记总结
一、查询 构造器分为QueryWrapper和LambdaQueryWrapper 创建实体类User package com.system.mybatisplus.model;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.…...
How Language Model Hallucinations Can Snowball
本文是LLM系列文章,针对《How Language Model Hallucinations Can Snowball》的翻译。 语言模型幻觉是如何产生雪球的 摘要1 引言2 为什么我们期待幻觉像滚雪球一样越滚越大?3 实验4 我们能防止雪球幻觉吗?5 相关工作6 结论局限性 摘要 在实…...
autojs修改顶部标题栏颜色
顶部标题栏的名字是statusBarColor 不是toolbar。难怪我搜索半天搜不到 修改之后变成这样了 代码如下: "ui"; importClass(android.view.View); importClass(android.graphics.Color); ui.statusBarColor(Color.parseColor("#ffffff")); ui.…...
arppy gis 读取text 并批量添加字段 arcpy.AddField_management
arppy gis 读取text 并批量添加字段 arcpy.AddField_management 例:给“省级行政区域”添加“A、B、C、D” 4个字段。 (1)用Excel制作出字段及其描述表,定义字段结构; (2)复制除标题行以为的内…...
Pandas中at、iat函数详解
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 at 函数:通过行名和列名来取值(取行名为a, 列名为A的值) iat 函数:通过行号和列号来取值(取第1行,第1列的值) 本文给出at、iat常见的…...
【Spring Boot】JPA — JPA入门
JPA简介 1. JPA是什么 JPA是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据,通过注解或者XML描述“对象-关系表”之间的映射关系,并将实体对象持久化到数据库中,极大地简…...
c#反射(Reflection)
当我们在C#中使用反射时,可以动态地获取和操作程序集、类型和成员。下面是一个简单的C#反射示例,展示了如何使用反射来调用一个类的方法: using System; using System.Reflection;public class MyClass {public void MyMethod(){Console.Wri…...
Lua 元表和元方法
一、元表 元表可以修改一个值在面对一个未知操作时的行为,Lua 中使用 table 作为元表的承载。 元表只能给出预先定义的操作集合的行为,比类会更加受限制,不支持继承。 Lua 每一个值都可以有元表 : 表和用户数据类型都具有各自…...
【Git】01-Git基础
文章目录 Git基础1. 简述1.1 版本管理演变1.2 Git的特点 2. Git安装2.1 安装文档2.1 配置user信息 3. 创建仓库3.1 场景3.2 暂存区和工作区 4. 重命名5. 常用git log版本历史5.1 查看当前分支日志5.2 简洁查看日志5.3 查看最近指定条数的日志 6. 通过图形界面工具查看版本7. 探…...
【Vue2.0源码学习】生命周期篇-初始化阶段(initState)
文章目录 1. 前言2. initState函数分析3. 初始化props3.1 规范化数据3.2 initProps函数分析3.3 validateProp函数分析3.4 getPropDefaultValue函数分析3.5 assertProp函数分析 4. 初始化methods5. 初始化data6. 初始化computed6.1 回顾用法6.2 initComputed函数分析6.3 defineC…...
专升本英语零基础学习
1. 词法 1.1 名词 名词(n.),是词类的一种,属于实词。他表示人,物,事,地点或抽象概念的统一名称。 1.1 名词的含义 名词(n.),是词类的一种,属于实词。他表示人&#x…...
QUIC协议连接详解(二)
目录 一:RTT解释 二:QUIC 1-RTT连接 三:QUIC 0-RTT连接 一:RTT解释 在介绍QUIC协议的连接之前先科普一下什么是RTT。RTT是Round-Trip Time的英文缩写,翻译过来就是一趟来回的时间即往返时延。时间计算即从发送方发送…...
JAVA 经常遇到一些问题【第二部分36~51】
重拾者: 每日记录至目前(记录51种不同场景的问题可参考解决方案) 异常就两部分: 1、excepiton信息: 报错产生的原因 2、at开头表示: 异常产生的代码位置。 欢迎关注本人微信公众号:AIM…...
蓝桥杯打卡Day6
文章目录 N的阶乘基本算术整数查询 一、N的阶乘OI链接 本题思路:本题是关于高精度的模板题。 #pragma GCC optimize(3) #include <bits/stdc.h>constexpr int N1010;std::vector<int> a; std::vector<int> f[N];std::vector<int> mul(in…...
spark集群问题汇总
一、 磁盘问题 问题描述可能原因解决措施core节点磁盘不足, 并且持续增加未开启spark-history的日志清理打开日志清理: spark.history.fs.cleaner.enabled task节点磁盘不足 APP应用使用磁盘过大: 1. 严重的数据倾斜 2. 应用本身数据量大 1. 解决数据倾斜 2. 加大资源, 增加e…...
WebServer 解析HTTP 请求报文
一、TCP 状态转换 浏览器访问网址,TCP传输全过程 二、TCP协议的通信过程 三、TCP 通信流程 // TCP 通信的流程 // 服务器端 (被动接受连接的角色) 1. 创建一个用于监听的套接字- 监听:监听有客户端的连接- 套接字:这…...
Golang开发--interface的使用
在Go语言中,接口(interface)是一种特殊的类型,它定义了一组方法的集合。接口为实现多态性提供了一种机制,允许不同的数据类型实现相同的方法,从而可以以统一的方式处理这些不同类型的对象。接口在Go中广泛用…...
2023 年高教社杯全国大学生数学建模竞赛题目 B 题 多波束测线问题
B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀速直线传播,在不同界面上产生反射,利用这一原理,从测量船换能器垂直向海底发射声波信号,并记录从声波发射到信号接收的传播…...
企业级浏览器自动化测试架构设计:Chrome for Testing的高可用解决方案与实践指南
企业级浏览器自动化测试架构设计:Chrome for Testing的高可用解决方案与实践指南 【免费下载链接】chrome-for-testing 项目地址: https://gitcode.com/gh_mirrors/ch/chrome-for-testing Chrome for Testing是Google ChromeLabs团队为解决浏览器自动化测试…...
透视 Mission Control 源码:如何构建高性能的 Agent 实时监控架构?
在 AI Agent 爆火的当下,我们正从“对话式 AI”迈向“行为式 AI”。然而,当数十个 Agent 同时运行,处理复杂的链上交易或长程任务时,开发者面临的最大挑战往往是:观测性(Observability)。你无法…...
Claude API预算与性能优化实战:四层策略降本增效
1. 项目概述:一个为Claude设计的预算与性能优化技能 最近在折腾Claude API的时候,发现了一个挺有意思的开源项目,叫 budget_and_performance_optimization_claude_skill 。简单来说,这是一个专门为Claude(特别是Clau…...
Systemback实战:从系统备份到自定义镜像部署全流程
1. Systemback基础入门:你的系统时光机 第一次听说Systemback时,我正面临着一个典型运维困境:实验室20台Ubuntu工作站需要统一部署开发环境。传统的手动安装方式不仅耗时,还容易产生配置差异。直到发现这个开源神器,才…...
IEA-15-240-RWT:15MW海上风机开源模型的完整入门指南
IEA-15-240-RWT:15MW海上风机开源模型的完整入门指南 【免费下载链接】IEA-15-240-RWT 15MW reference wind turbine repository developed in conjunction with IEA Wind 项目地址: https://gitcode.com/gh_mirrors/ie/IEA-15-240-RWT 你是否曾经想要研究海…...
Boss-Key:办公隐私保护神器,一键隐藏敏感窗口的智能解决方案
Boss-Key:办公隐私保护神器,一键隐藏敏感窗口的智能解决方案 【免费下载链接】Boss-Key 老板来了?快用Boss-Key老板键一键隐藏静音当前窗口!上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在当今…...
实测Taotoken在低功耗arm7设备上的API调用延迟与稳定性表现
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 实测Taotoken在低功耗arm7设备上的API调用延迟与稳定性表现 1. 测试背景与目的 在边缘计算或资源受限的嵌入式场景中,…...
河南AI设计课程指南:机构推荐与避坑秘籍
一、AI 设计热潮下的河南求学路在数字化时代的浪潮中,AI 设计正以前所未有的速度席卷各个行业,成为了创新与效率的新代名词。从广告设计、影视制作到电商运营、交互设计,AI 设计不仅能够大幅提升设计效率,还能通过数据分析和算法模…...
0403开源:第四卷光刻机整机控制与量检测系统(A级 中期集中攻坚)3. 开源纳米级计量检测设备卡点
开源光刻机整机控制与量检测系统(A级 中期集中攻坚) 3. 开源纳米级计量检测设备卡点(全参数开源硬核壁垒拆解喂饭级溯源破局) 前置开源声明 本节全程无保留开源光刻量检测底层原理、设备架构、纳米级计量阈值、国内外参数对标、核…...
英雄联盟智能助手:从青铜到王者的全方位游戏体验升级指南
英雄联盟智能助手:从青铜到王者的全方位游戏体验升级指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 想要在英雄联盟中获得竞争…...
