Spring Boot加密配置文件方法介绍
作者:做网安的小王 发布时间:2023-09-11 17:15:58
在实践中,项目的某些配置信息是需要进行加密处理的,以减少敏感信息泄露的风险。比如,在使用Druid时,就可以基于它提供的公私钥加密方式对数据库的密码进行加密。
但更多时候,比如Redis密码、MQ密码等敏感信息,也需要进行加密,此时就没那么方便了。本篇文章给大家介绍一款Java类库Jasypt,同时基于Spring Boot项目来演示一下如何对配置文件信息进行加密。
一个简单的SpringBoot项目
我们先来创建一个简单的Spring Boot项目,构建一个加密数据运用的场景。
无论通过Idea或官网等方式,先创建一个Spring Boot项目,核心依赖为:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 为了方便,通常会引入Lombok依赖 -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
创建一个配置文件类ConfigProperties:
@Data
@Component
public class ConfigProperties {
@Value("${conf.url}")private String url;
@Value("${conf.password}")private String password;
}
配置文件中的配置属性注入到该类,以供后续使用。
创建一个Controller类,用来测试验证,是否能够正常运行:
@RestController
@RequestMapping("/")
public class ConfigController {
@Resourceprivate ConfigProperties configProperties;
@RequestMappingpublic void print(){System.out.println(configProperties.getUrl());System.out.println(configProperties.getPassword());}
}
对应ConfigProperties类,application.properties中配置如下:
conf.url=127.0.0.1
conf.password=admin123
此时,启动项目,访问Controller,能够正常打印出配置信息,说明程序可以正常运行。
但配置文件中直接明文展示了password项,如果别人看到该配置文件,就可能导致密码的泄露。
基于Jasypt的加密
针对上述情况,通常,我们会对敏感信息进行加密,避免明文密码信息暴露,提升安全等级。
加密的基本思路是:配置文件中存储加密内容,在解析配置文件注入时进行解密。
但如果拿到项目源码,知道加密算法和秘钥,肯定是可以解密的。这里的加密,只是多一层安全防护,但并不是万能的。
下面看看如何基于Jasypt来进行加密处理。
集成步骤
下面基于上述Spring Boot项目进行改造升级。
环境准备
不同版本的Jasypt使用方法有所不同,这里基于3.0.4版本、JDK8、Spring Boot 2.5.5来进行演示。
在使用之前,首先检查一下JDK8的JRE中是否安装了不限长度的JCE版本,否则在执行加密操作时会抛出解密失败的异常。
进入$JAVA_HOME/jre/lib/security目录,查看是否包含local_policy.jar和US_export_policy.jar两个jar包。如果不包含,则通过Oracle官网进行下载,下载地址:https://pan.baidu.com/s/1pLUNUBvF6TWudeYcf5BNjA?pwd=qgk9。
下载文件为:jce_policy-8.zip
文件内包含三个文件:
README.txt
local_policy.jar
US_export_policy.jar
查看$JAVA_HOME/jre/lib/security目录下是否有这两个jar包文件,如果没有则复制进去,如果有可考虑覆盖。
引入依赖
在Spring Boot中集成Jasypt比较简单,直接引入如下依赖即可:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
此时,Jasypt组件自动配置便已经生效,只需要对需要加密的数据进行处理了。
为了方便对密码进行加密,还可以在pom.xml中的build元素中引入对应的plugin,这个后面会用到:
<plugin><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-maven-plugin</artifactId><version>3.0.4</version>
</plugin>
至此,所有的准备工作已经完成。
内容加密
内容加密有多种方式,这里挑选两种方式进行介绍。
方式一:单元测试类生成密文;
构建如下单元测试类,使用默认实例化的StringEncryptor对密码进行加密:
@SpringBootTest
class SpringBootJasyptApplicationTests {
@Autowiredprivate StringEncryptor stringEncryptor;
@Testvoid contextLoads() {String qwerty1234 = stringEncryptor.encrypt("admin123");System.out.println(qwerty1234);}
}
其中,”admin123“便是要加密的内容。执行上述程序,便可打印加密后的内容。这种形式加密的内容,全部采用默认值。
方式二:通过Maven插件生成密文
在上面已经引入了Jasypt的Maven插件,可通过对应的命令进行生成密码。
第一步:在配置文件中添加加密的密码:
jasypt.encryptor.password=afx11
然后对配置文件中需要加密的数据进行改造,在数据前添加”DEC(“,在数据尾部加上")",修改完如下:
conf.password=DEC(admin123)
这里添加的DEC()是告诉插件,此部分内容需要进行加密处理。注意这里关键字是DEC。
第二步:执行Maven命令,对上述数据进行加密处理
在命令执行以下命令:
mvn jasypt:encrypt -Djasypt.encryptor.password=afx11
此时再看配置文件中的conf.password数据已经变为:
jasypt.encryptor.password=afx11
conf.url=127.0.0.1
conf.password=ENC(209eBdF3+jsV2f8kDjs4NOCzgBxnVgETlR5q2KfhYo5DW2jqvLknv0TndEkXOXm0)
注意原来的DEC变成了ENC,原来的明文密码变成了加密的密文。
此时,如果想查看明文,执行以下命令即可:
mvn jasypt:decrypt -Djasypt.encryptor.password=afx11
该命令不会修改配置文件中的密文为明文,只会在控制台进行明文结果的输出。
jasypt.encryptor.password=afx11
conf.url=127.0.0.1
conf.password=DEC(admin123)
经过上述操作,所有改造步骤已经完成,只需启动系统进行验证即可。
密码的传递方式
完成上述步骤,直接启动系统,访问对应的请求,会发现已经能够成功打印出密码原文了。
上述实例中我们将加密的密码放在了application.properties文件中,这样并不安全,如果查看代码就知道如何解密了。通常,还可以采用另外一种形式来传递参数:在启动命令中传输密码。
比如:
java -jar jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar --jasypt.encryptor.password=password
这样,密码便不用存储在代码当中了,一定程度上增加了安全性。当然,也可以通过环境变量来进行传递,这样即便开发人员也无法获得生产的密码。
来源:https://blog.csdn.net/text2201/article/details/128684632


猜你喜欢
- 什么是有序性在开发中,我们通常按照从上到下的顺序编写程序指令,并且希望cpu和编译器按照我们预先编写的顺序去执。但往往cpu和编译器为了提高
- 起因最近在写CRUD的时候,发现有个分页的VO写的健壮性比较差,一时手痒改了一下,没想到改了之后好几个功能都出现了问题。原VO关键代码如下:
- 一、线程同步概述前面的文章都是讲创建多线程来实现让我们能够更好的响应应用程序,然而当我们创建了多个线程时,就存在多个线程同时访问一个共享的资
- 在定义一个Rest接口时通常会利用GET、POST、PUT、DELETE来实现数据的增删改查;这几种方式有的需要传递参数,后台开发人员必须对
- 目录多通道分离API操作通道合并API操作结果源码多通道分离APIpublic static void split(Mat m, List&
- 一个Resty项目包含的部分(resty-route):1. RestFilter像其他web框架一样,Resty也需要一个入口,在web.
- 本文实例讲述了Android编程实现任务管理器的方法。分享给大家供大家参考,具体如下:任务管理器可以实现的功能有:1.查看当前系统下运行的所
- 在Spring4之后,要使用注解开发,必须要保证aop的包导入了使用注解需要导入context约束,增加注解的支持!<?xml ver
- 本文实例为大家分享了java金额数字转中文工具类的具体代码,供大家参考,具体内容如下java金额数字转中文工具类ConvertNum.jav
- 一、前言随着互联网项目前后端分离方式的流行,前端与后端交给不同的人员开发,项目沟通成本也随之提高。主要表现在WebAPI接口的沟通,Swag
- 前面已经认识了不同的数据类型,你们有没有尝试过让不同的数据类型进行运算呢?int a = 1;double b = a;Console.Wr
- 数据存储与访问常用方式:文件SharedPreferences(偏好参数设置)SQLite数据库内容提供者(Content provider
- 本文实例为大家分享了C语言自定义扫雷游戏的具体代码,供大家参考,具体内容如下实现过程对于用C语言实现扫雷游戏得实现,可将游戏过程分为两个板块
- 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。深刻认识Stri
- 滚轮选择控件Android自带的选择时间控件有点丑,往往产品和设计都比较嫌弃,希望做成ios一样的滚轮选择,下面是我在NumberPicke
- 在定义API的时候,对于一些返回集合对象的方法,很多人喜欢将返回类型定义成IEnumerable<T>,这本没有什么问题。这里要
- 今天Android Studio提示我这个东东。。。为了加快Gradle的构建速度,我点击了“Update”。。。之后工程一片红,全是R文件
- C#字符集编码的使用ASCII:西欧字符集GB2312:国家简体中文字符集,兼容ASCII。BIG5:统一繁体字编码GBK:它是GB2312
- 在重写类UsernamePasswordAuthenticationFilter时抛出了这个异常,字面上理解是authenticationM
- 在程序设计过程中,我们总是希望自己设计的程序是天衣无缝的,但这几乎又是不可能的。即使程序编译通过,同时也实现了所需要的功能,也并不代表程序就