SrpingDruid数据源加密数据库密码的示例代码

前言

在工作中遇到这样一个问题:开发过程中将数据库的账号、密码等信息配置在了一个单独的properties配置文件中(使用明文)。但运维人员要求在配置文件中的密码一律不得出现明文。

环境

  1. Spring 4.2.6.RELEASE
  2. MyBatis 3.4.1
  3. Druid 1.0.14

改造思路

一般spring容器启动时,通过PropertyPlaceholderConfigurer类读取jdbc.properties文件里的数据库配置信息。通过这个原理,我们把加密后的数据库配置信息放到jdbc.properties文件里,然后自定义一个继承PropertyPlaceholderConfigurer的类重写processProperties方法,实现解密,把解密后的信息又放回去。

而Druid已经帮我们实现了上面的功能,我们只需要更改相关的配置即可。

1.生成数据库密码密文,替换明文。

2.更改spring配置文件中的数据源配置,开启数据库密码解密。

改造过程

项目源码地址

生成密文

在druid-1.0.14.jar所在目录执行命令

代码如下:

java -cp druid-1.0.14.jar com.alibaba.druid.filter.config.ConfigTools <YOUR_DB_PASSWORD>

生成对应的密文,复制到数据库配置文件中。

更改Druid数据源配置

开启数据库密码解密,在<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean>

中添加如下属性:

<property name="connectionProperties" value="config.decrypt=true" />

遇到的问题

遇到以下错误:

[20/10/17 12:30:29:029 CST] Druid-ConnectionPool-Create-1225284770 ERROR pool.DruidDataSource: create connection error, url: jdbc:mysql://localhost:3306/common?useUnicode=true&characterEncoding=utf-8
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
  at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1084)
  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:926)
  at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1748)
  at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1288)
  at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2506)
  at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2539)
  at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2321)
  at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:832)
  at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
  at sun.reflect.GeneratedConstructorAccessor4.newInstance(Unknown Source)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
  at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
  at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:417)
  at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:344)
  at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:148)
  at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:211)
  at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:142)
  at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1377)
  at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1431)
  at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:1861)

也就是说,加解密并没有生效,因此数据库认为密码错误,拒绝连接。

经对比,发现数据源中的<property name="filters" value="mergeStat" />属性值不对,应该为<property name="filters" value="stat,config" />

为什么filters为mergeStat就不对呢?

查看src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java源码:

在注释43行,可以看到dataSource.setFilters("config");,因此这里不是说mergeStat不行,而是缺少config的配置。

更多配置请参考wiki

总结

  1. 必须为spring项目,否则无法生效。在只含MyBatis和Druid(不含spring)的程序中使用上面的改造,发现还是无法正确连接数据库。
  2. Druid dataSource配置中filters属性不应为mergeStat,否则无法生效。
  3. 为Druid数据源打call,说它是优秀的Java数据源一点也不为过。

升级druid到高版本

参考资料:druid wiki:使用ConfigFilter

主要变化有两处:

1.生成的密码有公钥、私钥、签名之分。

2.配置文件中需要配置签名和公钥,spring配置文件也需要相应更改为:

代码如下:

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

错误:failed to decrypt 和 java.security.NoSuchAlgorithmException:Cannot find any provider supporting RSA/ECB/PKCS1Padding

进一步说明:该问题在Eclipse直接启动中不会出现,但部署到服务器上会出现。

原因:在解密步骤中出错,找不到支持RSA/ECB/PKCS1Padding等和解密相关的算法相关的提供者。

解决:将${JAVA_HOME}\lib\ext目录下的sunjce_provider.jar添加到classpath目录下。

补充:在Druid github issues中作者温少将该问题标记为bug,但我认为这只是环境问题,不属于Druid本身的bug。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Boot使用和配置Druid

    1.引入依赖包 <!--druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.27</version> </dependency> 2.配置application.properties spring.datasource.type=com.alibaba.dru

  • Spring Boot使用Druid进行维度的统计和监控

    Druid Druid:一款为监控而生的数据库连接池框架,整个项目由数据库连接池.插件框架和SQL解析器组成. Druid功能介于PowerDrill和Dremel之间,它几乎实现了Dremel的所有功能,并且从PowerDrill吸收一些有趣的数据格式.Druid允许以类似Dremel和PowerDrill的方式进行单表查询,同时还增加了一些新特性,如为局部嵌套数据结构提供列式存储格式.为快速过滤做索引.实时摄取和查询.高容错的分布式体系架构等. Spring Boot spring框架作为J

  • Spring Boot使用Druid和监控配置方法

    Spring Boot默认的数据源是:org.apache.tomcat.jdbc.pool.DataSource Druid是Java语言中最好的数据库连接池,并且能够提供强大的监控和扩展功能. 下面来说明如何在 Spring Boot 中配置使用Druid (1)添加Maven依赖 (或jar包)\ <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId&g

  • 详解Spring Boot下Druid连接池的使用配置分析

    引言: 在Spring Boot下默认提供了若干种可用的连接池,Druid来自于阿里系的一个开源连接池,在连接池之外,还提供了非常优秀的监控功能,这里讲解如何与Spring Boot实现集成. 1.  环境描述 spring Boot 1.4.0.RELEASE,  JDK 1.8 2.   Druid介绍 Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource 高效可管理的数据

  • 数据库阿里连接池 druid配置详解

    Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,有不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色的性能,也逐渐印入了大家的眼帘.接下来本教程就说一下druid的简单使用. 首先从 http://repo1.maven.org/maven2/com/alibaba/druid/下载最新的jar包.如果想使用最新的源码编译,可以从 https://github.com/alibaba/druid下载源码,然

  • Spring Boot 使用Druid详解

    Druid是Java语言中最好的数据库连接池,并且能够提供强大的监控和扩展功能,下面来说明如何在 SpringBoot 中配置使用Druid. 步骤: 1. 在pom.xml中加载依赖 2. 在application.properties中加入数据源配置 3. 编写DruidConfiguration,通过@Bean注解的方式注入druid servlet和filter,以便提供监控页面访问 4. 浏览器访问 一.在pom.xml中加入依赖 <dependency> <groupId&g

  • Spring Boot集成Druid数据库连接池

    1. 前言 Druid数据库连接池由阿里巴巴开源,号称是java语言中最好的数据库连接池,是为监控而生的.Druid的官方地址是:https://github.com/alibaba/druid 通过本文,我们可以看到 Spring Boot 如何配置数据源 Spring Boot 如何集成Druid数据库连接池 如何打开并访问Druid数据库连接池的监控功能 Spring Boot 使用JdbcTemplate操作数据库 2. 配置pom.xml <parent> <groupId&g

  • SrpingDruid数据源加密数据库密码的示例代码

    前言 在工作中遇到这样一个问题:开发过程中将数据库的账号.密码等信息配置在了一个单独的properties配置文件中(使用明文).但运维人员要求在配置文件中的密码一律不得出现明文. 环境 Spring 4.2.6.RELEASE MyBatis 3.4.1 Druid 1.0.14 改造思路 一般spring容器启动时,通过PropertyPlaceholderConfigurer类读取jdbc.properties文件里的数据库配置信息.通过这个原理,我们把加密后的数据库配置信息放到jdbc.

  • C++解密Chrome80版本数据库的方法示例代码

    谷歌浏览器Google Chrome 80正式版例行更新详细版本80.0.3987.163.Google Chrome浏览器又称谷歌浏览器采用Chromium内核全球最受欢迎的免费网页浏览器追求速度.隐私安全的网络浏览器. 先说下吧.chrome80以前的版本是直接可以通过DPAPI来进行解密的.关于DPAPI 大家可以 看这里的介绍 DPAPI是Windows系统级对数据进行加解密的一种接口无需自实现加解密代码微软已经提供了经过验证的高质量加解密算法提供了用户态的接口对密钥的推导存储数据加解密

  • springboot多数据源配置及切换的示例代码详解

    注:本文的多数据源配置及切换的实现方法是,在框架中封装,具体项目中配置及使用,也适用于多模块项目 配置文件数据源读取 通过springboot的Envioment和Binder对象进行读取,无需手动声明DataSource的Bean yml数据源配置格式如下: spring: datasource: master: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver url:

  • Springboot Druid 自定义加密数据库密码的几种方案

    前言 开发过程中,配置的数据库密码通常是明文形式,这样首先第一个安全性不好(相对来说),不符合一个开发规范(如项目中不能出现明文账号密码),其实就是当出现特殊需求时,比如要对非运维人员开方服务器部分权限,但是又涉及项目部署的目录时,容易泄漏数据库密码,虽然一般生产环境中,数据库往往放入内网,访问只能通过内网访问,但是不管怎么说账号密码直接让人知道总归不好,甚至有些项目需要部署到客户环境中,但是可能共用一个公共数据库(数据库只向指定服务器开放外网端口或组建内网环境),这样的情况下,如果数据库密码再

  • Python实现对word文档添加密码去除密码的示例代码

    代码实现如下: import win32com.client,os,time def word_encryption(path, password): # 若加密保存.docx时,覆盖原文件,则无法成功添加密码.但是保存为另一个文件名,则可以添加密码. # 因此将A存为B,删A,再将B改为A. dirname, tempname = os.path.split(path) path_temp = os.path.join(dirname, tempname) while os.path.exis

  • Springboot2 集成 druid 加密数据库密码的配置方法

    一:环境 springboot 2.x druid 1.1.21 二:druid加密数据库密码 本地下载druid-1.1.21.jar包,运行cmd,输入命令 java -cp jar包路径 com.alibaba.druid.filter.config.ConfigTools 数据库密码 java -cp druid-1.1.21.jar com.alibaba.druid.filter.config.ConfigTools 数据库密码 运行成功输出 privateKey:MIIBVAIBA

  • git设置用户名密码的示例代码

    git设置用户名密码 设置git用户名/邮箱 git config --global user.name [username] git config --global user.email [email] 但是这个仅仅是设置用户名密码,如果你的git 源每次操作需要你输入用户名/密码验证,你依然需要每次设置,那么该如何办呢? git保存用户名密码 这里主要是配置一个config项 有两个方法,基本上原理都是一样,都是修改.git/config文件 1.使用如下命令,修改config文件即可保存

  • Golang实现AES加密和解密的示例代码

    目录 对称加密 AES 算法 加解密 文件加密解密 说明 对称加密 AES 算法 (Advanced Encryption Standard ,AES) 优点 算法公开.计算量小.加密速度快.加密效率高. 缺点 发送方和接收方必须商定好密钥,然后使双方都能保存好密钥,密钥管理成为双方的负担. 应用场景 相对大一点的数据量或关键数据的加密. 加解密 package helpers import ( "bytes" "crypto/aes" "crypto/c

  • java实现波雷费密码算法示例代码

    一.算法描述 波雷费密码是一种对称式密码,是首种双字母取代的加密法. 下面描述算法步骤: 1.从1号二维码M05,提取明文信息和密文,M05格式:<xxx-xxx|yyy-yyy>,其中明文xxx-xxx,密钥部分信息为yyy-yyy中的提取所有英文字母信息. 2.将提取的英文字母作密匙.除去重复出现的字母.将密匙的字母逐个逐个加入5×5的矩阵内,剩下的空间将未加入的英文字母依A-Z的顺序加入.(将Q去除) 3.将要加密的讯息分成两个一组.若组内的字母相同,将X加到该组的第一个字母后,重新分组

  • java用户名密码验证示例代码分享

    类:NameII    权限:public方法:main    权限:public 参数:name,password,denglu,i;参数介绍:name,数据类型 String ,用来存储一个从 input 中获取的值,在本程序当中用作用户名的存放:password,数据类型 String ,用来存储一个从 input 中获取的值,在本程序当中用作密码的存放:denglu,数据类型 boolean,用来存储默认账户的登录状态,true 表示登录成功,false 表示尚未登录:i,数据类型 in

随机推荐