Druid官方提供数据密码加密 和 DruidDataSource源码解读

一、Druid官方提供数据密码加密

1、执行命令加密数据库密码,在【druid-1.0.16.jar】下,打开cmd可以直接执行。(com.alibaba.druid.filter.config.ConfigFilter类中有说明参数配置意义)
java -cp druid-1.0.16.jar com.alibaba.druid.filter.config.ConfigTools 数据库密码
生成结果:公私钥和密码密文
privateKey:********************************
publicKey: ********************************
password: ********************************
2、jdbc配置
① 增加参数:
druid.publickey =公钥字符串
② 更改参数
druid.password=明文 变更成 druid.password=密文
druid.filters=stat 变更成 druid.filters=stat,config
3、spring-mybatis.xml配置
① 增加name = connectionProperties的配置

 <property name ="connectionProperties"  value="config.decrypt=true;config.decrypt.key=${druid.publickey}" />

注:config.decrypt=true表示启动加密;config.decrypt.key表示公钥信息

**

二、自定义数据库密码加密方法及配置

**
1、程序代码DBPasswordCallback类

	@Override  
	public void setProperties(Properties properties) {
		log.debug("数据源的连接池加载中...,加载次数:第{}次;共耗时:{} 秒", i++, (System.currentTimeMillis() - now) / 1000 );
		
		// 1. 判断数据库密码是否已被加载
		if (getPassword() != null) {
			return;
		}
		
		// 2. 获取配置的参数值
		String pwd = properties.getProperty("password");
		if (StringUtil.isBlank(pwd)) {
			return;
		}
		String pubpath = properties.getProperty("pubpath");
		if (StringUtil.isBlank(pubpath)) {
			pubpath = "路径(自定义),如:D:/druid/";
		}
		
		try {
			// 3. 根据路径获取公钥信息
			InputStream is = new FileInputStream(pubpath);
			int iAvail = is.available();
			byte[] bytes = new byte[iAvail];
			is.read(bytes);
			String pubkey = new String(bytes).trim();
			is.close();
			
			// 4. 解密
			String password = decrypt(pwd, pubkey);
			setPassword(password.toCharArray());
		} catch (Exception e) {
			setPassword(pwd.toCharArray());
			log.error("类DBPasswordCallback---->密码解密失败", e);
		}
	}
	
	/**
	 * 解密
	 * @param pwd
	 * @param pubkey
	 * @return
	 * @throws Exception
	 */
	private String decrypt(String pwd, String pubkey) throws Exception {
		PublicKey publicKey = ConfigTools.getPublicKey(pubkey);
		String password = ConfigTools.decrypt(publicKey, pwd);
		return password;
	}

2、jdbc配置
① 增加参数:
druid.publickey =公钥字符串
② 更改参数
druid.password=明文 变更成 druid.password=密文
druid.filters=stat 变更成 druid.filters= stat,config
3、spring-mybatis.xml配置
① 对使用解密的类注入

<bean id="dbPasswordCallback" 
class="com.lyb.baseUtil.datasource.DBPasswordCallback" lazy-init="true"/>

② 增加对passwordCallback 的引用和name= connectionProperties的配置

<property name="passwordCallback" ref="dbPasswordCallback"/>
<!-- 加密后的密码 -->
<property name="connectionProperties" 
value="password=${druid.password};pubkey=${druid.publickey}" />

三、公私钥和密码密文生成工具

1、内部执行代码和jar包:
java -cp druid-1.0.16.jar com.alibaba.druid.filter.config.ConfigTools 数据库密码

2、工具双击就会生成

3、jar和工具下载地址
链接:https://pan.baidu.com/s/1un8GwFXWhV4Lqp-5EpIJUA
提取码:15f6

四、DruidDataSource源码解读

1、解读来源:因为密码加密缘故,如果没有配置解密文件,就会造成连接池不断的重连,造成数据库用户被锁住(数据库配置了超过密码输入错误次数,就会锁定;严重会影响交易)。

2、初步配置方式:
① 重连次数:5 (本身次数1次 + 重连次数 + 1) < 触发用户被锁次数;breakAfterAcquireFailure配置true。

注:如果执行了break,项目需要重新启动(不然线程池连接不会重新连接)。【+1是因为errorCount > connectionErrorRetryAttempts;如果配置次数是5必须6次重试错误,才会触发断开】。

② 重连次数:3 (本身次数1次 + 重连次数 + 1) < 触发用户被锁次数;timeBetweenConnectErrorMillis时间配置大些5~10分钟,可以检查出程序是否有问题。

注:不会执行break,只要连接正常了,线程池连接会重新连接

3、xml数据源配置

<!-- 线程池重连次数:默认30次 -->
<property name="connectionErrorRetryAttempts" value="30" />

<!-- 数据库服务宕机自动重连机制:false表示不重连,true表示重连(默认false) -->
<property name="breakAfterAcquireFailure" value="false" />

<!-- 连接出错后重试时间间隔(默认30秒) -->
<property name="timeBetweenConnectErrorMillis" value="30000" />

<!-- 源码判断是否重连:errorCount连接失败次数,breakAfterAcquireFailure判断是否跳出-->
for (;;) {
	.... 省略代码(正常情况不会退出for循环,线程抛出中断异常Interrupted时,会退出)
	if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
		if (breakAfterAcquireFailure) {
			break;
		}

		try {
			Thread.sleep(timeBetweenConnectErrorMillis);
		} catch (InterruptedException interruptEx) {
			break;
		}
	}
	.... 省略代码(正常情况不会退出for循环,线程抛出中断异常Interrupted时,会退出)
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值