数据库密码直接写在配置中,对运维安全来说,是一个很大的挑战。可以使用​​Druid​​​为此提供一种数据库密码加密的手段​​ConfigFilter​​。

目录

​1、执行命令加密数据库密码​

​2、配置数据源,提示Druid数据源需要对数据库密码进行解密​

​3、DruidProperties配置connectProperties属性​

​4、启动应用程序测试验证加密结果​


1、执行命令加密数据库密码

java -cp druid-1.2.4.jar com.alibaba.druid.filter.config.ConfigTools password

 ​​password​​输入你的数据库密码,输出的是加密后的结果.

需要用的jar包:下载链接:​​https://pan.baidu.com/s/1rhy0z0CfOrcils668sgWow ​​  提取码:wj3u 

//私钥
privateKey:MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmsk4TVK1qwohS9QA0VUk/4UbIUXkYgoEFLuv+dr60yOrA9ViVWCM1mCKi4fTShZaV5Gq9gCOwl1oPs+yKbYBIQIDAQABAkEAiz7L3Ju0fJsPWxTsa2UKdKf8wREMJLpX84LpC3/Yt0lv52Z4N97vzCL2H3obeAOHLbqlif0ke2biaIQWAwZGdQIhAMmXFs9V/U1FWgnHY2iSTqwDHGMJ3q4I5Sgsj5hHu/v/AiEAxJAwEQtZgYcaydND1ATPSZ8R7Dn77Of8TfOO1cECgt8CIBHiO33NTRlry58Odz0xrZUI+Z23pG+gDmRP/7Ust/qVAiAeKSG2+87YGSr7HPejaLmFymqtnJgTWeVU8LJSCjOgcQIgLOSFy2Wx3DJTAdS1cmwLagMFoJxYOjGlIlafwdE/deI=

//公钥
publicKey:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJrJOE1StasKIUvUANFVJP+FGyFF5GIKBBS7r/na+tMjqwPVYlVgjNZgiouH00oWWleRqvYAjsJdaD7Psim2ASECAwEAAQ==

//加密后的密码
password:JY80Fdc+K2oJHXI153NEtuWaf+/LYv8BSBMQd+CJzmQcr70Ylh7E8Z1D9bsYjpN07OIE3iFqMvHYzf/P89+zPQ==

2、配置数据源,提示​​Druid​​数据源需要对数据库密码进行解密

# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: JY80Fdc+K2oJHXI153NEtuWaf+/LYv8BSBMQd+CJzmQcr70Ylh7E8Z1D9bsYjpN07OIE3iFqMvHYzf/P89+zPQ==
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 公钥
connectProperties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJrJOE1StasKIUvUANFVJP+FGyFF5GIKBBS7r/na+tMjqwPVYlVgjNZgiouH00oWWleRqvYAjsJdaD7Psim2ASECAwEAAQ==
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username:
login-password:
filter:
config:
# 是否配置加密
enabled: true
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true

3、​​DruidProperties​​​配置​​connectProperties​​属性

package com.framework.config.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;

/**
* druid 配置属性
*/
@Configuration
public class DruidProperties
{
@Value("${spring.datasource.druid.initialSize}")
private int initialSize;

@Value("${spring.datasource.druid.minIdle}")
private int minIdle;

@Value("${spring.datasource.druid.maxActive}")
private int maxActive;

@Value("${spring.datasource.druid.maxWait}")
private int maxWait;

@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;

@Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;

@Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
private int maxEvictableIdleTimeMillis;

@Value("${spring.datasource.druid.validationQuery}")
private String validationQuery;

@Value("${spring.datasource.druid.testWhileIdle}")
private boolean testWhileIdle;

@Value("${spring.datasource.druid.testOnBorrow}")
private boolean testOnBorrow;

@Value("${spring.datasource.druid.testOnReturn}")
private boolean testOnReturn;

@Value("${spring.datasource.druid.connectProperties}")
private String connectProperties;

public DruidDataSource dataSource(DruidDataSource datasource)
{
/** 配置初始化大小、最小、最大 */
datasource.setInitialSize(initialSize);
datasource.setMaxActive(maxActive);
datasource.setMinIdle(minIdle);

/** 配置获取连接等待超时的时间 */
datasource.setMaxWait(maxWait);

/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

/** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);

/**
* 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
*/
datasource.setValidationQuery(validationQuery);
/** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
datasource.setTestWhileIdle(testWhileIdle);
/** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource.setTestOnBorrow(testOnBorrow);
/** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource.setTestOnReturn(testOnReturn);

/** 为数据库密码提供加密功能 */
datasource.setConnectionProperties(connectProperties);
return datasource;
}
}

4、启动应用程序测试验证加密结果

tips:如若忘记密码可以使用工具类解密(传入生成的公钥+密码)

public static void main(String[] args) throws Exception
{
String password = ConfigTools.decrypt(
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJrJOE1StasKIUvUANFVJP+FGyFF5GIKBBS7r/na+tMjqwPVYlVgjNZgiouH00oWWleRqvYAjsJdaD7Psim2ASECAwEAAQ==
password:JY80Fdc+K2oJHXI153NEtuWaf+/LYv8BSBMQd+CJzmQcr70Ylh7E8Z1D9bsYjpN07OIE3iFqMvHYzf/P89+zPQ==",
"JY80Fdc+K2oJHXI153NEtuWaf+/LYv8BSBMQd+CJzmQcr70Ylh7E8Z1D9bsYjpN07OIE3iFqMvHYzf/P89+zPQ==");
System.out.println("解密密码:" + password);
}