作为程序员每天的开发工作都离不开跟数据库打交道,而且我们的应用程序往往都会配置数据库的链接,那你有没有想过,任何一个能接触到我们项目代码的人员,都可以看到配置文件里面的账号秘密?
相信很多人的项目里面配置文件都是类似这样写的
1 |
|
spring.datasource.url
中配置了数据库的链接地址和端口,spring.datasource.username
配置了账号以及spring.datasource.password
中配置了密码。
如果是这样的写法,无非就是在裸奔,任何一个能接触到这个文件的人,都能够用 MySQL
的客户端工具进行数据库的链接,里面的数据毫无安全可言。当然如果是本地或者测试环境都还可以,但是对于生产环境那是不能接受的,毕竟这样的安全性太差了,一不小心被删库跑路还是有可能的。
相对而言,有一些经验的数据库运维人员是不会直接提供数据库服务的 IP
地址和端口的,而是提供域名,通过在 url
地址上面配置相应的域名,然后通过解析域名让其访问数据库服务,域名地址是不对外解析的,所以生产环境的主机以及开发人员的本机,需要进行 hosts
的配置,将域名对应 IP
地址配置起来。
这种方式会比上面直接裸奔的形式好一点,外人拿到代码,没有 hosts
配置也是不能访问数据库的,难度相对来说高了一点。但是这样也有个问题,那就是开发人员还是可以通过 MySQL
的客户端进行数据的访问,如果哪天心情不好,删库跑路也不是没有可能,或者说私自泄露数据也是有机会的。
那么很多小明就问了,有没有一种方式,可以有效的控制这种情况呢?让尽量少了人接触到数据库的数据,但是同时也不能影响开发的进度,对于开发要友好。
有问题,就会有答案,这个时候我们就需要介绍一款神器了,那就是 jasypt
。jasypt
可以帮助我们在配置文件中配置加密后的账号和密码,然后结合秘钥,就可以完全控制数据库的安全性。下面我们就来试一下吧。
首先有一个需要连接数据库的 Spring Boot
服务,我们先看一下,在没有引入 jasypt
的时候,是如何使用的,代码如下:
1 |
|
UserController.java
1 |
|
UserMapper.java
1 |
|
另外我们有一张表,表里面的数据是这样的,接下来我们启动服务,调用接口查询表的数据,如下所示
说明在使用明文账号密码的时候,整个流程是没有问题,接下来,我们引入 jasypt
,主要分下面三个步骤
-
引入
pom
依赖1
2
3
4
5
6<!--springboot整合jasypt--> <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>1.18</version> </dependency>
-
编写加密工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class JasyptUtil { public static void main(String[] args) { String account = "root"; String password = "123456"; BasicTextEncryptor encryptor = new BasicTextEncryptor(); //秘钥 //encryptor.setPassword(System.getProperty("jasypt.encryptor.password")); encryptor.setPassword("eug83f3gG"); //密码进行加密 String newAccount = encryptor.encrypt(account); String newPassword = encryptor.encrypt(password); System.out.println("加密后账号:" + newAccount); System.out.println("加密后密码:" + newPassword); } }
因为我们要得到加密后的密文,所以我们先需要根据原始账号密码,以及我们指定的秘钥来生成加密后的密文,这里我们假设本地和测试环境的秘钥为
eug83f3gG
,通过上面的工具类,我们可以生成如下的密文 -
替换账号密码,我们将 application.properties 里面的账号密码用上面的密文替换,如下所示,使用
ENC()
包住密文。
1 |
|
这里说明三点
- 此时我们还不能正常启动服务,因为就这样的话是启动不成功了,账号和密码是错误的,我们需要将秘钥传入,让
jasypt
给我们反向解析出正确的账号和密码才能进行数据库的链接; - 工具类中的秘钥保持跟生产环境不一样!!!
- 使用
ENC()
包住密文;
接下来我们可以将秘钥通过两种形式传进程序中使用,一种是将秘钥通过系统环境变量的形式进行配置,不过不建议;第二种是通过启动参数将秘钥进行传入;这里我们使用第二种,在 SpringBoot
项目的启动参数中,我们增加这样的配置 -Djasypt.encryptor.password=eug83f3gG
,然后我们再重启应用,就可以启动成功了。
启动成功了再次访问上面的接口,可以看到效果是一样的。
后续在生产环境中,只需要在启动参数中传入与本地和测试环境不一样的秘钥,就可以有效的防止数据库的账号密码被泄露了,就连开发人员都不知道是什么,只要配置的运维人员知道,这个安全性就高很多了,怎么样小伙伴你学会了吗?赶紧在自己的项目中用起来吧!