前言

我们在开发的时候,都会把源代码上传到代码托管平台,例如:GitHub,Gitlab 等,但是这样有一个问题,会存在泄露的风险,而数据库连接信息作为源码的一部分,一旦泄露,后果不堪设想

为了避免这个问题,我们至少要对数据库的密码进行加密

所以我们就使用阿里巴巴提供的 Druid 来进行加密

What is Druid

Druid(中文译为德鲁伊) 是阿里开源的连接池,是 Java 语言中最好的数据库连接池,Druid 能够提供强大的监控和扩展功能,是为监控而生的数据库连接池!

GitHub 地址:

images

使用 Druid 加密

运行环境

  • Spring Boot 2.4.3
  • MySQL 5.7
  • Java 1.8
  • Maven 3.6.3
  • IntelliJ IDEA 2020.3.2

这里我直接用上上篇的 Spring Boot 整合 MyBatis 的案例进行演示

首先添加 Druid 依赖

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>

生成密文

使用 Druid 提供的 ConfigTools 类来加密,代码如下

1
2
3
public static void main(String[] args) throws Exception {
ConfigTools.main(new String[]{"此处写你的数据库密码"});
}

执行结果如下

1
2
3
privateKey:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAtjXeooEqq5GFiBsFe/pvJ7CUdea0D2lZQwroX+9iGvqA+eODkXlxAvWJpLJvb556e+bvE4PTSKOnqG1WGYbExwIDAQABAkBXQYTUHTbp4k4n14jQziTcxNrFbqUk5TfXE3KZ1sEo5/dYSAaKKrH1RvCv1Qq1BAiEA/Iwg1Iv3/+/wageQysq3donzE3InTOlMjyWmljPS75MCIQC4s5MKdTPgpCgLCPrrTCoIwWbGCCRux6Cjt32/KvNOfQIgWdRCDTgoI1omKqC8SNWoQjq5Qm51Oi81sykSQxT1748CIFbUDIb5DBdJ9I0jfpoI5yXQjZkBEOeHLyxnwVSSQ2kdAiBJGgYiTzuCAr0IVndmXHD1ExmPBlPeNqnZGQT56joMeQ==
publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALY13qKBKquRhYgbBXAsdq13KNASD9pWUMK6F/vYhr6gPnjg5F5cQL1iaSyb2+eenvm7xOD00ijp6htVhmGxMcCAwEAAQ==
password:Jriab0IWm8Ibx88A91oFk5VP8crpLnU96fy+jAjb4MKOSAD6ZPezPYL6QZMIAlGEym6oXBzedKS/AZOKcEH+Iw==
  • privateKey:私钥,暂时用不到,用于密码的加密
  • publicKey:公钥,用于密码的解密
  • password:加密以后的密码

要实现数据库的加密,主要使用 publicKey(公钥)和 password(密文),这样就把明文转换成密文了。

配置 application.yaml

原始的数据库配置还记得吗?

images

而使用 Druid 进行加密之后

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
# 配置数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql:///mybatis?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
username: root
password: Jriab0IWm8Ibx88A91oFk5VP8crpLnU96fy+jAjb4MKOSAD6ZPezPYL6QZMIAlGEym6oXBzedKS/AZOKcEH+Iw==
filters: config
connect-properties:
config.decrypt: true
config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALY13qKBKquRhYgbBXAsdq13KNASD9pWUMK6F/vYhr6gPnjg5F5cQL1iaSyb2+eenvm7xOD00ijp6htVhmGxMcCAwEAAQ==

password 对应上一步用 ConfigTools 类生成的 passwordconfig.decrypt.key 对应 publicKey

如此如此,启动项目,可以发现能正常访问

start

但是你们有没有发现到一个问题,就是公钥和密文都写在配置文件里了,万一有人拿到公钥和密文,那不就可以解密了…

解决思路

我们可以在启动项目的时候将公钥动态的设置到项目中,说白了就是设置环境的参数,如此密码就有保障了

再次修改 application.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
spring:
# 配置数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql:///mybatis?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false
username: root
password: Jriab0IWm8Ibx88A91oFk5VP8crpLnU96fy+jAjb4MKOSAD6ZPezPYL6QZMIAlGEym6oXBzedKS/AZOKcEH+Iw==
# encrypt config
filters: config
connect-properties:
config.decrypt: true
config.decrypt.key: ${druid.publickey}

mybatis:
type-aliases-package: cn.imzjw.entity
mapper-locations: classpath:mapper/*.xml

公钥修改成 ${druid.publickey}

druid.publickey 是自定义的,并不是固定的写法

最后设置环境参数

images

以上都是在开发的时候操作的,如果是生产环境中,可以参考如下命令:

1
java -jar xxx.jar --druid.publickey=公钥

images

解密操作

1
2
3
4
5
public static void main(String[] args) throws Exception {
String publickey = "公钥";
String password = "密文";
LOGGER.info(ConfigTools.decrypt(publickey, password));
}