1. 背景
基于Springboot的工程项目,通常很多信息都是在application.yml中直接明文配置的,比如数据库链接信息,redis链接信息等;
为了安全考虑,公司打算将yml配置文件中的数据库连接信息的账号,密码进行加密!
公司有开发相关的安全规定,要求对源代码工程中所有的敏感信息进行加密,包括代码和配置文件,防止密码泄露;
实际上没太大必要——咋办呢,有专员检查,做还是得做;
2. 方案
初步想了下方案,有2种:
(1)依赖配置中心
一般来说,配置中心实现了业务配置的在线管理,能实时查看修改业务配置,不需要重启项目;
其原理是维护本地和远程配置中心的长连接,本地监听远程配置的变更,刷新本地配置的缓存;
常见的有nacos、apollo之类的;
(2)基于Springboot框架
在spring工程启动时,会读取yml文件中的配置到配置对象中;在这一步,可以切入,引入加解密工具库;
实际上,刚好有这么一个常用的库来解决这个问题——Jasypt这个库为我们解决了这个问题,实现了springboot配置的自定加密加密;
本次由于工程是轻量级,未使用远程配置中心中间件,因此为了快速解决问题,使用轻量级的方案——即引入Jasypt对yml配置加密;
3. Maven引入本地二方包
在准备使用Jasypt时,去maven仓库搜索maven坐标,发现公司的仓库并没有引入这个包,需要自己去公网公网下载Jasypt库相关的jar包;
所以先要解决的问题是——如何在maven工程中引入本地二方包?
方案可以参考:
这里简单描述下步骤:
(1)去外网下载jar包,在resource下,新建lib文件夹,复制“xx.jar”;
(2)在pom.xml引入依赖;把地址替换成本地的jar包文件相对地址;
(3)在Maven打包插件处进行配置,允许本地系统的二方包;
<configuration>
<!--允许导入本地二方包-->
<includeSystemScope>true</includeSystemScope>
<executable>true</executable>
</configuration>
成功引入后,编译工程,可以通过maven helper查看到相关依赖已经引入,如下:
注意:网上搜到的引入包仅包含,但是发现其依赖的包仍然不在公司仓库里,所以需要层层把仓库里不存在的包都引入,所以这里引入了3个包,其他的如spring-framework相关的包公司仓库已经有了,所以无需手动引入;
4. Springboot引入Jasypt对yml配置加密
网上搜了很多方法都走不通,所以这里还是完整的记录下步骤,亲测能通:
(1)引入jar包
<!--本地二方包jasypt-->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-stater</artifactId>
<version>2.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jasypt-spring-boot-starter-2.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot</artifactId>
<version>2.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jasypt-spring-boot-2.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jasypt-1.9.2.jar</systemPath>
</dependency>
(2)写测试类生成数据库密码明文对应的密码
@Test
public void testEncrypt() {
StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
EnvironmentPBEConfig config = new EnvironmentPBEConfig();
config.setAlgorithm("PBEWithMD5AndDES");
config.setPassword("my-encryptor");
standardPBEStringEncryptor.setConfig(config);
String plainText = "ab123";
String encryptedText = standardPBEStringEncryptor.encrypt(plainText);
System.out.println(encryptedText);
}
(3)写测试类测下解密
@Test
public void testDecrypt() {
StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
EnvironmentPBEConfig config = new EnvironmentPBEConfig();
config.setAlgorithm("PBEWithMD5AndDES");
config.setPassword("my-encryptor");
standardPBEStringEncryptor.setConfig(config);
String encryptedText = "JD1Ez9hxgHXNpIj4+E......";
String plainText = standardPBEStringEncryptor.decrypt(encryptedText);
System.out.println(plainText);
}
(4)yml配置替换成密文,使用ENC(*)包裹
(5)启动服务,测试数据库连接
注意:尽量使用2.X低版本的Jasypt依赖,因为博主在使用3.x的版本时启动遇到了各种疑难杂症,所以如果不是有特殊要求,仅仅是解决加密问题,就尽量使用2.X版本;
参考文章:
maven工程引用仓库中没有的包
手动导入Maven库中不存在的jar包并整合打包
对spring boot yml配置文件敏感信息加密处理的两种方式
如何给yml配置文件的密码加密(SpringBoot)