Spring Boot配置加密实践
Spring Boot配置加密实践
使用Java技术栈的时候,Spring Boot几乎已经成为了标配。Spring Boot帮助我们简化了各种技术的整合,我们只需要在application.yml配置文件中增加一点点的配置即可。
虽然Spring Boot简化了我们的工作,但是也隐藏了底层的整合实现。
现在有一个问题,我们的数据库密码、Redis密码、ES密码等等都设置在application.yml中,那岂不是有安全风险。能不能对这些敏感字段进行加密?
答案当然是可以的。
那么就开始这个文档的主题,加密Spring Boot配置中的敏感数据。
提前预告,内容过于简单,请不要太开心。
配置加密初体验
今天介绍的配置加密,使用了这个包jasypt-spring-boot-starter
,废话不多说,开始整合。
-
这里假设你是使用Maven构建的项目(使用Gradle的话,自己对应变更就好了),在pom.xml文件中加入
jasypt-spring-boot-starter
的依赖。<!-- 属性加密工具 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.4</version></dependency>
-
在pom.xml中加入对应的插件。
<!-- 配置加密插件 --><plugin><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-maven-plugin</artifactId><version>3.0.4</version></plugin>
-
在你的启动参数中,加入如下参数
jasypt.encryptor.password
java -jar xxx.jar -Djasypt.encryptor.password="test"
记住
jasypt.encryptor.password
表示的就是你的加密的密码,这个是必须要设置的。现在示例密码是test
。其实除了设置到启动参数中,也可以设置到
application.yml
中,虽然这样是不推荐的,毕竟这样的话,你的加密后的密码跟加密密码就放到一起了,容易被解密。jasypt:encryptor:password: test
现在加密使用的工具就整合结束了,是不是很简单。
使用配置加密
整合配置加密的工具后,如果你的配置中没有设置加密的密码,是不会影响使用的。
那要如何开启密码加密呢。
第一步 对密码进行加密
这就要使用到我们刚才设置的插件jasypt-maven-plugin
。
使用如下命令,即可对密码进行加密。
mvn jasypt:encrypt-value -Djasypt.encryptor.password="test" -Djasypt.plugin.value="xxx"
-Djasypt.encryptor.password
我们之前也已经介绍了,表示的是加密的密码。
-Djasypt.plugin.value
表示的是我要进行加密的内容,例如数据库的密码。
在命令行中执行之后,就得到了加密后的密码,如下图所示。
我们得到的加密后的密码就是ENC(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
第二步 替换密码
我们需要使用第一步得到的加密密码来替换我们的原始密码。对应到配置上应该就是:
spring:datasource:password: ENC(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
好了,结束了,现在你就可以启动你的系统了,是不是发现,加密后的密码竟然也可以启动你的系统。
现在你的系统中任何系统属性、环境属性、命令行参数、application.properties、application-*.properties 、yaml属性和任何其他属性源都可以包含加密属性。
特殊的加密整合
虽然使用jasypt-spring-boot-starter
来进行配置加密已经很简单了,但是奈何现实情况是多种多样的,总有可能出现问题。下面讲解下我遇到的各种问题,以及解决办法。
配置关键字被占用
通过之前的了解,我们也知道了,在配置中,加密后的敏感数据是这样的形式的:ENC(xxx)
xxx是加密后的内容,ENC()
是帮助jasypt-spring-boot-starter
识别那些是加密的数据,需要解密的。
但是,不是只有jasypt-spring-boot-starter
会进行加密解密的,其他的工具也可能会有加密解密功能,也可能会使用ENC()
作为识别加密属性的关键字。
假如跟其他的工具使用相同的关键字,那到底是谁来解密呢,解密的工具不对,那解密就会失败的呀。
很不巧,dynamic-datasource-spring-boot-starter
就是这样的工具。
这个工具用来支持多数据源,也是很常见的一种工具。通过查看文档,发现他也是使用ENC作为加密字段的关键字。
博主在使用过程中,发现了密码被dynamic-datasource-spring-boot-starter
率先解密,导致解密失败。
如何解决?
那就给jasypt-spring-boot-starter
换一个识别加密字段的关键字就好了。如下配置所示:
jasypt:encryptor:property:prefix: ENCRYPT(suffix: )
现在识别加密密码的关键字已经换成了ENCRYPT()
,这个换成你喜欢的就行。
那么我现在的密码,应该是:
spring:datasource:password: ENCRYPT(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
Redisson配置没有加解密
在实践过程中,还发现了Redisson配置没有加解密成功。配置所下所示:
spring:redis:redisson:config: |sentinelServersConfig:password: ENCRYPT(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
这是因为jasypt-spring-boot-starter
识别加密字段的逻辑是,以关键字ENC(
开头,)
结尾,中间的就是加密的内容。
我们查看上面的配置,发现了redisson的配置是一个多行文本,即不是一个以关键字ENC(
开头,也不是)
结尾。所以识别失败,不会进行解密。
通过断点查看类RedissonAutoConfiguration
也发现了,redission的密码确实是没有加密的,依旧使用的是ENCRYPT(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
不过,好在redission给我们提供了自定义配置的方式。源码中如下图表示:
所以我们需要提供一个Bean,实现接口RedissonAutoConfigurationCustomizer
,用于修改redisson的密码,使用spring.redis.password
配置的密码即可。
/*** Redisson密码将使用spring.redis.password的密码,这是因为处理在Jasypt配置加密解密整合过程中,发现redisson的密码不被解析的问题。** @author wanggt* @date 2023-07-26 17:29:31*/
@Component
public class RedissonPasswordCustomizer implements RedissonAutoConfigurationCustomizer {@Autowiredprivate RedisProperties redisProperties;@Overridepublic void customize(Config configuration) {// spring.redis.password的密码是被解密过的,设置给redisson使用configuration.useSentinelServers().setPassword(redisProperties.getPassword());}
}
只需要设置spring.redis.password的密码为加密密码即可。
spring:redis:password: ENCRYPT(Zdy/wU1qeh9OHHtWGgQkZBxJ7ArACrdrkBrW9gVGltYenncnUzHi6WtRJuR9VS3y)
这样redisson的问题也解决了。
整合报错
Failed to bind properties under ‘spring.datasource.password’ to java.lang.String
部分人在整合之后,启动系统失败,出现了这样的报错。
出现这样的报错通常都是解密失败,需要排查:
-
yaml文件格式是否正确,是否缺少了属性冒号后的空格
-
是否缺少了JCE的包。
可以在命令行执行命令
mvn jasypt:decrypt-value -Djasypt.encryptor.password="test" -Djasypt.plugin.value="xxx"
,查看是否可以解密。-Djasypt.plugin.value
设置的是加密后的密码,如果出现下图提示,可能就是缺少的JCE。可以考虑更换JDK版本,如果是JDK8,需要是JDK8u161版本以上。
链接
加密工具Github
相关文章:

Spring Boot配置加密实践
Spring Boot配置加密实践 使用Java技术栈的时候,Spring Boot几乎已经成为了标配。Spring Boot帮助我们简化了各种技术的整合,我们只需要在application.yml配置文件中增加一点点的配置即可。 虽然Spring Boot简化了我们的工作,但是也隐藏了底…...
SwiftUI-基础
应用入口 Main函数与App结构体的绑定,遵循App协议 main struct BaseApp: App {var body: some Scene {WindowGroup {ContentView()}} } 兼容UIApplicationDelegate main struct BasicApp: App {UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate…...
vue。cli怎么使用自定义组件,会有哪些问题
在Vue CLI中使用自定义组件的步骤如下: 通过仔细检查以上问题并按照正确的步骤使用自定义组件,大多数问题都可以解决。此外,查看开发者工具的控制台输出和Vue警告信息,可以帮助你进一步调试和解决可能出现的问题 创建自定义组件&a…...
linux----vim的使用
vi和vim是Linux下的一个文本编辑工具,最小化安装只有vi vim,需要额外安装,比vi更强大一些 # vim 操作文件,有三种模式:普通模式,编辑模式,命令模式 -vim 文件名刚进来----》普通模式--》只…...

95. Python基础教程:异常处理try...except语句
【目录】 文章目录 1. try...except语法解析2. 程序异常3. except的4种使用方式3.1 单独的except3.2 except 异常名称3.3 except 异常类型 as 别名3.4 except (异常类型1,异常类型2) as 别名 4. 总结 【正文】 1. try…except语法解析 try[traɪ]:尝试。 except[…...

详解rocketMq通信模块升级构想
本文从开发者的角度深入解析了基于netty的通信模块, 并通过简易扩展实现微服务化通信工具雏形, 适合于想要了解netty通信框架的使用案例, 想了解中间件通信模块设计, 以及微服务通信底层架构的同学。希望此文能给大家带来通信模块架构灵感。 概述 网络通信是很常见的需求&#…...
【BOOST程序库】对字符串的处理
基本概念这里不解释了,代码中详细解释了BOOST程序库中对于字符串每一个方法的详细用法: 注意:这里每实践一个方法,都将上面实践过的方法进行了注释,如果全部取消注释,会出现重命名的问题。 #include <…...

(学习笔记-内存管理)虚拟内存
单片机是没有操作系统的,每次写完代码,都需要借助工具把程序烧录进去,这样程序才能跑起来。另外,单片机的CPU是直接操作内存的[物理地址]。 在这种情况下,要想在内存中同时运行两个程序是不可能的。如果第一个程序在 2…...

JVM理论(七)性能监控与调优
概述 性能优化的步骤 性能监控:就是通过以非强行或入侵方式收集或查看应用程序运行状态,包括如下问题 GC频繁CPU过载过高OOM内存泄漏死锁程序响应时间较长性能分析:通常在系统测试环境或者开发环境进行分析 通过查看程序日志以及GC日志,或者运用命令行工…...

复现YOLOv8改进最新MPDIoU:有效和准确的边界盒回归的损失,打败G/E/CIoU,效果明显!!!
MPDIoU: A Loss for Efficient and Accurate Bounding Box Regression 论文简介MPDIoU核心设计思路论文方法实验部分加入YOLOv5代码论文地址:https://arxiv.org/pdf/2307.07662.pdf 论文简介 边界盒回归(Bounding box regression, BBR)广泛应用于目标检测和实例分割,是目标…...

LT6911C 是一款HDMI 1.4到双端口MIPIDSI/CSI或者LVDS加音频的一款高性能芯片
LT6911C 1.描述: LT6911C是一款高性能的HDMI1.4到MIPIDSI/CSI/LVDS芯片,用于VR/智能手机/显示器应用程序。对于MIPIDSI/CSI输出,LT6911C具有可配置的单端口或双端口MIPIDSI/CSI,具有1个高速时钟通道和1个~4个高速数据通道&#…...

vue动态引入静态资源
vue动态引入静态资源 静态资源位置(../../assets/piecture/page404.jpg)或者(/assets/piecture/page404.jpg) 错误引入方式 错误引入方式(一) <template><div><img :src"../../asset…...
perl 强制覆盖拷贝文件
如果你想在Perl中进行文件拷贝时强制覆盖目标文件(如果目标文件已经存在),你可以使用标准模块File::Copy提供的cp函数,它允许你指定是否覆盖目标文件。 以下是一个示例,展示了如何在Perl中进行强制覆盖拷贝文件&#…...

C语言每日一题之整数求二进制1的个数
今天分享一道题目,用三种方法来求解 二进制1的个数 方法1 我们的十进制除10和取余数就可以得到我们每一位的数字,那我们的二进制也可 以 #include<stdio.h> int num_find_1(unsigned int n) {int count 0;while (n){if (1 n % 2){count;}n / 2…...
AcWing 4443.无限区域
原题链接:AcWing 4443.无限区域 题目来源:夏季每日一题2023 给定一个无限大的二维平面,设点 S 为该平面的中心点。 设经过点 S 的垂直方向的直线为 P,如果直线 P 是一个圆的切线,且切点恰好为点 S,那么&a…...

2D坐标系下的点的转换矩阵(平移、缩放、旋转、错切)
文章目录 1. 平移 (Translation)2. 缩放 (Scaling)3. 旋转 (Rotation)4. 错切 (Shearing)5. 镜像 (Reflection) 1. 平移 (Translation)…...
【Rabbitmq】报错:ERROR CachingConnectionFactory Channel shutdown: channel error;
报错内容 ERROR CachingConnectionFactory Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code406, reply-textPRECONDITION_FAILED - unknown delivery tag 1, class-id60, method-id80) 原因 默认是自动ack,然后你代码…...
el-table组件的el-table-column电脑端使用fixed属性固定,移动端不使用固定,怎么实现?
要在电脑端使用 fixed 固定列,而在移动端不使用,可以使用 CSS 媒体查询结合 Vue 的动态绑定来实现。以下是一个示例代码: <template><el-table><el-table-columnprop"name"label"Name":fixed"isDesk…...

RocketMQ 行业分享
5.0的架构发生了重大调整,添加了一层rocketmq-proxy,可以通过grpc的方式接入。 参考 https://juejin.cn/post/7199413150973984827...

物联网场景中的边缘计算解决方案有哪些?
在物联网场景中,边缘计算是一种重要的解决方案,用于在物联网设备和云端之间进行实时数据处理、分析和决策。HiWoo Box作为工业边缘网关设备,具备边缘计算能力,包括单点公式计算、Python脚本编程以及规则引擎,它为物联网…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...