转载请注明出处:https://blog.csdn.net/l1028386804/article/details/79920338

Druid是阿里巴巴开发的一款数据库连接池,它支持对数据库密码的加密操作,今天我们就一起来实现如何利用Druid对数据库的密码进行加密操作。

1、首先配置Druid的数据库连接池

<!--数据源加密操作-->
<bean id="dbPasswordCallback" class="com.lyz.dbsource.DBPasswordCallback" lazy-init="true"/><bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true"><property name="logSlowSql" value="true"/><property name="mergeSql" value="true"/></bean>
<!-- 数据库连接 -->
<bean id="readDataSource" class="com.alibaba.druid.pool.DruidDataSource"destroy-method="close" init-method="init" lazy-init="true"><property name="driverClassName" value="${driver}"/><property name="url" value="${url1}"/><property name="username" value="${username}"/><property name="password" value="${password}"/><!-- 初始化连接大小 --><property name="initialSize" value="${initialSize}"/><!-- 连接池最大数量 --><property name="maxActive" value="${maxActive}"/><!-- 连接池最小空闲 --><property name="minIdle" value="${minIdle}"/><!-- 获取连接最大等待时间 --><property name="maxWait" value="${maxWait}"/><!-- --><property name="defaultReadOnly" value="true"/><property name="proxyFilters"><list><ref bean="statFilter"/></list></property><property name="filters" value="${druid.filters}"/><property name="connectionProperties" value="password=${password}"/><property name="passwordCallback" ref="dbPasswordCallback"/><property name="testWhileIdle" value="true"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="validationQuery" value="SELECT 'x'"/><property name="timeBetweenLogStatsMillis" value="60000"/><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}"/><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}"/>
</bean>

其中要注意的是:

<bean id="dbPasswordCallback" class="com.lyz.dbsource.DBPasswordCallback" lazy-init="true"/><property name="connectionProperties" value="password=${password}"/>
<property name="passwordCallback" ref="dbPasswordCallback"/>

2、使用RSA公钥和私钥,生成一对公钥和私钥的工具类

package com.lyz.crypto.rsa;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;/*** RSA算法* @author liuyazhuang**/
public class RSAKeysUtil {public static final String KEY_ALGORITHM = "RSA";public static final String SIGNATURE_ALGORITHM = "MD5withRSA";private static final String PUBLIC_KEY = "RSAPublicKey";private static final String PRIVATE_KEY = "RSAPrivateKey";public static void main(String[] args) {Map<String, Object> keyMap;try {keyMap = initKey();String publicKey = getPublicKey(keyMap);System.out.println(publicKey);String privateKey = getPrivateKey(keyMap);System.out.println(privateKey);} catch (Exception e) {e.printStackTrace();}}public static String getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);byte[] publicKey = key.getEncoded();return encryptBASE64(key.getEncoded());}public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PRIVATE_KEY);byte[] privateKey = key.getEncoded();return encryptBASE64(key.getEncoded());}public static byte[] decryptBASE64(String key) throws Exception {return (new BASE64Decoder()).decodeBuffer(key);}public static String encryptBASE64(byte[] key) throws Exception {return (new BASE64Encoder()).encodeBuffer(key);}public static Map<String, Object> initKey() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<String, Object> keyMap = new HashMap<String, Object>(2);keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;}
}

运行这个类,输出的结果如下:

上边是公钥下边是私钥。

3、使用私钥对明文密码进行加密

package com.lyz.dbsource.demo;import com.alibaba.druid.filter.config.ConfigTools;/*** @author liuyazhuang**/
public class ConfigToolsDemo {/*** 私钥对数据进行加密*/private static final String PRIVATE_KEY_STRING = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKtq3IJP5idDXZjML6I8HTAl0htWZSOO43LhZ/+stsIG50WsuW0UJ2vdrEtjvTEfJxP6N1VNrbsF9Lrsp6A4AyUwx00ZUueTlbUaX60134Di0IdQ3C4RTt5mPIbF3hUKers8csltgYR4fByvR3Eq4lt+jAolVHKmyzufukH3d3vJAgMBAAECgYBXiyW+r4t9NdxRMsaI9mZ5tncNWxwgAtOKUi/I1a4ofVoTrVitqoNPhVB+2BtBQQW2IC2uNROq1incZQxeuPxxZJgz1lnnZyHvDE3wuMZAGTcalID+5xBZ2j6fBtDnxbfIL/tIfGJrX+0mUXP2LIo242yQIlzr7RV60iuE2Ms54QJBAOqE0ycvztfxubqBWO7l8PsS3qDUv9lLBBO/Q8I+qVl4tzh+SD/13BqLuaj9eWPGPyml+faWtbmuQgBqauT23l0CQQC7HmMC0CgZS6taQxmPkXzw0XhxZ7tBZeLWl87hqc2S79P0BPX9kPukiC4LpA5xyz0CZ5azJXd2EwRsxF32GERdAkASEi4bJOnxZeUD5BewQPOyxR92kS4/VjJ4OxLDkwSFqnGj3sc+dnmBaibiSLXj5FDVqr56K97Q8gaP9aNLBWLZAkEAjwGnPBQoQUTinaZgl6fibA47VbiolU+v8L+u3iqvMVhXjcxo0DUJDXMCdeUZIQDqDLdsplfBGB1qqVHeWeGsBQJAXGNe2I510WLjMdn+olhi5ZjMr4F4oiF8TAE1Uu74FWn0sc418E7ScgXPCgpGVK0QaXo2wtDeMIoxJwm9Zh8oyg==";// @Test
//    public void demo() throws Exception {
//        //密码明文,也就是数据库的密码
//        String plainText = "cardiochina.net123456";
//        System.out.printf(ConfigTools.encrypt(PRIVATE_KEY_STRING, plainText));
//    }public static void main(String[] args) throws Exception {//密码明文,也就是数据库的密码String plainText = "root";System.out.printf(ConfigTools.encrypt(PRIVATE_KEY_STRING, plainText));}
}

结果如下:

然后将数据库配置的链接密码改为这个输出结果如下:

jdbc.username=root
jdbc.password=EA9kJ8NMV8zcb5AeLKzAsL/8F1ructRjrqs69zM70BwDyeMtxuEDEVe9CBeRgZ+qEUAshhWGEDk9ay3TLLKrf2AOE3VBn+w8+EfUIEXFy8u3jYViHeV8yc8Z7rghdFShhd/IJbjqbsro1YtB9pHrl4EpbCqp7RM2rZR/wJ0WN48=

4、解析密码的时候需要的Callback类

package com.lyz.dbsource;import java.util.Properties;import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.util.DruidPasswordCallback;/*** 数据库密码回调* @author liuyazhuang**/
public class DBPasswordCallback extends DruidPasswordCallback {private static final long serialVersionUID = -4601105662788634420L;/*** password的属性*/private static final String DB_PWD = "password";/*** 数据对应的公钥*/public static final String PUBLIC_KEY_STRING = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCratyCT+YnQ12YzC+iPB0wJdIbVmUjjuNy4Wf/rLbCBudFrLltFCdr3axLY70xHycT+jdVTa27BfS67KegOAMlMMdNGVLnk5W1Gl+tNd+A4tCHUNwuEU7eZjyGxd4VCnq7PHLJbYGEeHwcr0dxKuJbfowKJVRypss7n7pB93d7yQIDAQAB";@Overridepublic void setProperties(Properties properties) {super.setProperties(properties);String pwd = properties.getProperty(DB_PWD);if (pwd != null && !"".equals(pwd.trim())) {try {//这里的password是将jdbc.properties配置得到的密码进行解密之后的值//所以这里的代码是将密码进行解密//TODO 将pwd进行解密;String password = ConfigTools.decrypt(PUBLIC_KEY_STRING, pwd); setPassword(password.toCharArray());} catch (Exception e) {setPassword(pwd.toCharArray());}}}
//  public static void main(String[] args) throws Exception{
//      System.out.println(ConfigTools.decrypt(PUBLIC_KEY_STRING, "fbTGHjui2zKUOBRiX/XYNvlBXTPGj4vXhOD7oh91cWvBvpf+ZsrAGDcVBwYfs2xqn5tWueC5VAI0o0nglV0R17PIata6OlVOr4hEvqID+x2nbhRBjxSfCMEwvVmdTFXahV1yuMMnLbi7FadbVuq10apTAGY1Ts5Vhuo1fNLyba4="));
//  }
}

其中PasswordCallback是javax.security.auth.callback包下面的,底层安全服务实例化一个 PasswordCallback 并将其传递给 CallbackHandler 的 handle 方法,以获取密码信息。

当然,除了使用上述的方式,自己也可以对应一套加解密方法,只需要在DBPasswordCallback的 String password = ConfigTools.decrypt(PUBLIC_KEY_STRING, pwd); 替换即可。

5、在jdbc.properties存放自己加密之后的信息

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
username=root#回调DBPasswordCallback解密,这里的密码是你加密之后的密码!!!
password=EA9kJ8NMV8zcb5AeLKzAsL/8F1ructRjrqs69zM70BwDyeMtxuEDEVe9CBeRgZ+qEUAshhWGEDk9ay3TLLKrf2AOE3VBn+w8+EfUIEXFy8u3jYViHeV8yc8Z7rghdFShhd/IJbjqbsro1YtB9pHrl4EpbCqp7RM2rZR/wJ0WN48=#定义初始连接数
initialSize=20
#定义最大连接数
maxActive=40
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

注意:2、3过程中密码的设置要确定,加密、解密的最初始密码是要对应的

6、设置自定义的DruidPasswordCallback

在自己的spring配置文件中加入下边的一句bean配置:

<!--数据源加密操作 这里的class就是第4步中自己创建的-->
<bean id="dbPasswordCallback" class="com.lyz.dbsource.DBPasswordCallback" lazy-init="true"/>

另外还可以直接继承自Spring提供的PropertyPlaceholderConfigurer,摘录别人一段代码大家参考一下:

public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer{/*** 重写父类方法,解密指定属性名对应的属性值*/@Overrideprotected String convertProperty(String propertyName,String propertyValue){if(isEncryptPropertyVal(propertyName)){return DesUtils.getDecryptString(propertyValue);//调用解密方法}else{return propertyValue;}}/*** 判断属性值是否需要解密,这里我约定需要解密的属性名用encrypt开头* @param propertyName* @return*/private boolean isEncryptPropertyVal(String propertyName){if(propertyName.startsWith("encrypt")){return true;}else{return false;}}
}

Druid之——连接池自定义数据库密码加解密的实现相关推荐

  1. Druid连接池自定义数据库密码加解密的实现

    Druid的功能 1.替换DBCP和C3P0.Druid提供了一个高效.功能强大.可扩展性好的数据库连接池. 2.可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能 ...

  2. 阿里巴巴云连接池durid数据库密码加密

    阿里巴巴连接池durid数据库密码加密      刘振兴     代码分享     2017年05月05日    374    暂无评论   先贴上本人durid 的配置 <!-- 阿里巴巴连接 ...

  3. druid连接池配置数据库密码加密

    druid配置数据库密码加密后,可以把密码放在配置文件里,或本地其他文件.远程服务器等三种地方,这里只讲第一种方法. 1.密码加密:cd到druid包所在文件夹打开命令行,输入 java -cp dr ...

  4. 【SpringBoot笔记】SpringBoot整合Druid数据连接池

    废话少说,按SpringBoot的老套路来. [step1]:添加依赖 <!-- 数据库连接池 --> <dependency><groupId>com.aliba ...

  5. Druid连接池实现数据库加密

    前言 不难发现,以我们现在的开发习惯,无论是公司的项目还是个人的项目,都会选择将源码上传到 Git 服务器(GitHub.Gitee 或是自建服务器),但只要将源码提交到公网服务器就会存在源码泄漏的风 ...

  6. Druid(德鲁伊)连接池

    Druid(德鲁伊)连接池是阿里提供的数据库连接池,集DBCP,C3P0,Proxool的优点于一身的数据库连接池,功能强大,速度快,稳定性好,具有强大的监控功能,也可以防止SQL的注入. 1.在使用 ...

  7. mysql连接池_数据库技术:数据库连接池,Commons DbUtils,批处理,元数据

    Database Connection Pool Introduction to Database Connection Pool 实际开发中"获得连接"或"释放资源&q ...

  8. Druid 数据源连接池配置

    在 Spring Boot 的配置文件中对 Druid 数据源连接池进行配置 # Druid连接池的配置 spring:datasource:druid:initial-size: 5 #初始化连接大 ...

  9. tomcat 配置 quercus记录:php使用连接池访问数据库

    安装好 quercus报错:  D:\apache-tomcat-5.5.27\webapps\wfx\conn\mysql.php:9: Warning: A link to the server ...

最新文章

  1. 【PC工具】更新百度网盘高速下载工具——亿寻使用方法及注意事项
  2. MySQL 避免行锁升级为表锁——使用高效的索引
  3. ECCV 2018 | 美图云联合中科院提出基于交互感知注意力机制神经网络的行为分类技术...
  4. 机器学习:朴素贝叶斯分类器代码实现,决策函数非向量化方式
  5. gradle创建web工程_Gradle入门:创建Web应用程序项目
  6. 在windows server2003邮件服务器的搭建
  7. Beta 冲刺 (6/7)
  8. 管理感悟:要想到自己脖子后面有灰
  9. EF批量添加数据BulkInsert
  10. 博德之门联机等待服务器响应,《博德之门》系列疑难解答
  11. 财务报表java_财务报表识别
  12. Mac下如何实现自动切换输入法
  13. 欧设传奇服务器修改充值记录,沙巴克传奇修改记录(包含详细修改路径)
  14. 未成熟男人; 成熟男人
  15. Transformer课程 业务对话机器人Rasa 3.x 运行命令学习
  16. 《从你的全世界路过》读后感
  17. 中国冶金工业节能减排规划及投资前景预测报告2022年
  18. monkey稳定性测试
  19. 使用Easyar在unity制作ar视频黑屏
  20. 安装SAS增强型编辑器资源和步骤

热门文章

  1. iOS OC语言(二) 类
  2. 用 Swift、Foursquare API 和 Realm 創建一個咖啡屋 App
  3. 电脑上有哪些好用的视频剪辑软件
  4. 除夕最绚丽3D烟花代码(html+音效)
  5. 一、Mahony姿态解算——坐标系变换
  6. DNS域名劫持的几种解决方法
  7. Andriod Scroller使用小结
  8. XMind商业思维导图——市场营销!
  9. C学习笔记——(4)数组和字符串说明,以及冒泡排序法
  10. 堆排序、归并排序、快速排序