问题背景:

快逸报表应用在tomcat应用服务器进行部署时,如果需要调用tomcat配置好的数据库连接池,就不得不把报表数据源连接的密码以明文形式暴露,这样数据库连接的用户名密码都非常容易被获取,是非常不安全的。本文将介绍如何对tomcat数据库连接池配置文件中的密码进行加密处理。

问题解决思路:

将配置文件用户相关的信息(例如:密码)进行加密使其以密文形式存在,进行初始化连接池的时候进行解密操作,达到成功创建连接池的目的。Tomcat默认使用DBCP连接池(基于common-pool的一种连接池实现),可在http://jakarta.apache.org/commons/dbcp/下载commons-dbcp源码包commons-dbcp-1.4-src.zip,对org.apache.commons.dbcp.BasicDataSourceFactory类修改,把数据库密码字段(加密后的密文)用解密程序解密,获得解密后的明文即可。

具体实现:

1.       修改org.apache.commons.dbcp.BasicDataSourceFactory类文件

找到数据源密码设置部分

value = properties.getProperty(PROP_PASSWORD);

if (value != null) {

dataSource.setPassword(value);

}

修改为:

value = properties.getProperty(PROP_PASSWORD);

if (value != null) {

dataSource.setPassword(Encode.decode(value));

}

将配置文件中的“密码”(加密后的结果)取出,调用加解密类中的解密方法Encode.decode(value)进行解密。

2.  加密类Encode.java,本例中使用加密解密模块比较简单只是用来说明问题,密文为明文的十六进制串。

public class Encode {

//编码-普通字符串转为十六进制字符串

public static String encode(String password){

String result = “”;

byte[] psd = password.getBytes();

for(int i=0;i<psd.length;i++){

result += Integer.toHexString(psd[i]&0xff);

}

return result;

}

//解码–十六进制字符串转为普通字符串

public static String decode(String password){

String result = “”;

password = password.toUpperCase();

int length = password.length() / 2;

char[] hexChars = password.toCharArray();

byte[] d = new byte[length];

for (int i = 0; i < length; i++) {

int pos = i * 2;

d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

}

result = new String(d);

return result;

}

//字符转字节

public static byte charToByte(char c) {

return (byte) “0123456789ABCDEF”.indexOf(c);

}

}

3.  数据库连接池文件,红色字体为数据源配置中密码设置,此时已经改为密文形式。

<?xml version=’1.0′ encoding=’utf-8′?>

<Context docBase=”reportmis” path=”/reportmis” privileged=”true” workDir=”work\Catalina\localhost\reportmis”>

<Resource auth=”Container” name=”mis2datasource” type=”javax.sql.DataSource”/>

<ResourceParams name=”mis2datasource”>

<parameter>

<name>password</name>

<value>696e65743231</value>

</parameter>

<parameter>

<name>url</name>

<value>jdbc:oracle:thin:@127.0.0.1:1521:orcl</value>

</parameter>

<parameter>

<name>driverClassName</name>

<value>oracle.jdbc.driver.OracleDriver</value>

</parameter>

<parameter>

<name>username</name>

<value>wanfang</value>

</parameter>

</ResourceParams>

</Context>

4.  将修改后的BasicDataSourceFactory.java和新添加的Encode.java编译后的class类文件重新打包进commons-dbcp-1.4.jar,将该包拷贝进tomcat下的common/lib目录中,重启tomcat。此时tomcat下部署的应用在连接数据源的时候都可以在不暴露密码明文的情况下进行连接。

问题补充:

1.       本例中用仅使用简单的加解密算法进行密文和明文的转化,可根据具体情况选择不同的加解密模块如MD5,base64,DES等。

2.       本例的实现中所有的连接池初始化操作均采用相同的加密解密方法,tomcat之下部署的应用可能是多个,强迫使用同一种方式不符合实际情形。可能出现以下场景:A_1项目利用B_1加解密模块,A_2项目利用B_2加解密模块,A_3项目不利用加解密模块等等,以上方式明显无法处理。BasicDataSourceFactory.java实现了接口javax.naming.spi.ObjectFactory,我们也实现该接口初始内容保持和BasicDataSourceFactory.java相同即可。只要可以在配置文件中控制加载当前配置文件类,即可达到加解密的目的。查阅JNDI设置相关知识发现Resource中有个参数factory,可以指定加载当前配置文件的类,若没有指定则默认采用BasicDataSourceFactory.java。也就是我们在设置不同数据库连接池时可以指定Resource的factory为不同,这样就可以实现不同应用采用不同的加密解密模块。

补充:

一、说明

Tomcat配置JNDI数据源时密码是以明文的形式出现在配置文件中,这样存在安全隐患,比较可取的方法是将配置文件用户相关的信息(例如:用户名、密码)进行加密使其以密文形式存在,进行初始化连接池的时候进行解密操作,达到成功创建连接池的目的。(附录是对tomcat加载过程的说明,若对其不明白请先阅读)

二、加密实现方式

第一种方式比较简单,直接修改BasicDataSourceFactory.java中读取加密字段部分

setPassword(value)----value是直接从配置文件中取到字符串值,此处加入解密方法获取明文即可达到目的。该方式优点是简单(网上相关介绍比较多),缺点也比较明显,适合于个人项目的实践练习,不适合与实际运行项目。修改BasicDataSourceFactory.java之后,所有的连接池初始化操作均采用相同的加密解密接口,tomcat之下部署的工程可能是多个公司,或者是一个公司不同时期的产品,强迫使用同一种方式不符合实际情形。可能出现以下场景:A_1项目利用B_1加解密模块,A_2项目利用B_2加解密模块,A_3项目不利用加解密模块等等,以上方式明显无法处理,所以其适用范围比较窄。

第二种方式比较专业,前提需要了解dbcp中的工厂模式。分析源代码可知BasicDataSourceFactory.java实现了接口javax.naming.spi.ObjectFactory,我们也实现该接口初始内容保持和BasicDataSourceFactory.java相同即可,之后修改参照第一种方式。只要可以在配置文件中控制加载当前配置文件类,即可达到加解密的目的。查阅JNDI设置相关知识发现Resource中有个参数factory,可以指定加载当前配置文件的类,若没有指定则默认采用BasicDataSourceFactory.java。

三、完整实例

(加密解密模块比较简单只是用来说明问题,密文为明文的十六进制串)

1>新建类HTBasicDataSourceFactory.java,内容与BasicDataSourceFactory.java完全一致。

2>HTBasicDataSourceFactory.java末尾添加如下内容

//编码-普通字符串转为十六进制字符串

public static String encode(String password){

String result = "";

byte[] psd = password.getBytes();

for(int i=0;i<psd.length;i++){

result += Integer.toHexString(psd[i]&0xff);

}

return result;

}

//解码--十六进制字符串转为普通字符串

public static String decode(String password){

String result = "";

password = password.toUpperCase();

int length = password.length() / 2;

char[] hexChars = password.toCharArray();

byte[] d = new byte[length];

for (int i = 0; i < length; i++) {

int pos = i * 2;

d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

}

result = new String(d);

return result;

}

//字符转字节

public static byte charToByte(char c) {

return (byte) "0123456789ABCDEF".indexOf(c);

}

4>打包为tomcat_dbcp_encrypt.jar,复制到Tomcat/lib目录,重新启动tomcat测试通过

附录:

Tomcat连接池采用DBCP(基于common-pool的一种连接池实现),上文就是修改dbcp源代码,BasicDataSourceFactory.java类包为org.apache.tomcat.dbcp.dbcp。下载DBCP源码之后需要确保包路径和tomcat/lib/tomcat_dbcp.jar中的一致(查看包路径方法:将jar包复制到WEB工程的lib中,)

下载DBCP源码,将common_pool.jar导入工程,还会提示工程报错,原因是缺少jta.jar。

如何实现Tomcat连接池数据库密码加密相关推荐

  1. TOMCAT 连接池数据库密码加密方法

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 原文来自 ...

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

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

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

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

  4. SSM项目的数据库密码加密方案

    项目主要采用:SpringMVC4.3.2.RELEASE +Spring4.3.2.RELEASE + Maven 3.3.3 + druid 1.0.29 + Mybatis 3.2.8 + My ...

  5. 集成druid实现数据库密码加密功能

    数据库密码直接写在配置中,对运维安全来说,是一个很大的挑战.可以使用Druid为此提供一种数据库密码加密的手段ConfigFilter. 目录 1.执行命令加密数据库密码 2.配置数据源,提示Drui ...

  6. Spring配置数据库密码加密

    在项目中,为了提高安全性,需要对配置文件中的部分敏感信息进行加密,如数据库登录密码等.以下是一个简单的数据库密码加密示例,供大家一起学习交流,有不对或者需要改进的地方,请大家多多指教! 一. 未加密情 ...

  7. SpringBoot集成Druid和数据库密码加密

    Druid是阿里开发的数据库连接池,通过简单的配置,可以实现数据库的连接,性能特别强大,可以在页面访问,包括监控数据库性能参数,慢SQL统计,当然还包括数据库连接等. 今天主要记录一下SpringBo ...

  8. tomcat连接池的配置与使用

    今天做接jsp的作业,在页面跳转的时候一直遇到个问题,"org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driv ...

  9. java配置文件中数据库密码加密

    最近,有位读者私信我说,他们公司的项目中配置的数据库密码没有加密,编译打包后的项目被人反编译了,从项目中成功获取到数据库的账号和密码,进一步登录数据库获取了相关的数据,并对数据库进行了破坏. 虽然这次 ...

最新文章

  1. django 模板语言之 simple_tag 自定义模板
  2. [svc]ext4文件删除访问原理
  3. office365加速解决方案
  4. 历史文件夹_Win10备份文件教程:备份到OneDrive,文件历史记录
  5. 事情在不断的解决中,想念巫英才和张国振
  6. hdu5709-Claris Loves Painting【线段树合并】
  7. Java面试10大知识点总结宝典助你通关!已拿意向书!
  8. Java 关键字—— static 与 final
  9. MySQL学习笔记_1_MySQL数据库管理系统概述
  10. 数据分析必备的统计学(二):假设检验
  11. android 存储盘 dcim,Android上的DCIM目录路径 – 返回值
  12. ul阻燃标准有几个等级_UL 阻燃标准
  13. win7一直显示正在启动_win7旗舰版升级后无法启动电脑的解决方法
  14. java服务端监控平台设计
  15. 《C程序设计》谭浩强
  16. 关于PSINS运动轨迹仿真模块的理解和思考
  17. 基于机器学习的心脏病预测方法(1)——心脏病及Heart Disease UCI数据集介绍
  18. 前端初中级面试题及部分答案
  19. 数字电子钟——期末数电大作业Multisim版
  20. 如何轻松停用WordPress插件(入门指南)

热门文章

  1. ssm+java计算机毕业设计拼车平台u5398(程序+lw+源码+远程部署)
  2. devstack在Centos7中安装教程
  3. eggjs validate no function 解决方案
  4. 数理逻辑 —— 德摩根定律
  5. fastText Python 教程
  6. window.onresize出现的问题
  7. IEEE VR 2022
  8. Python小常识(二)
  9. Ubuntu14.04 科学计算包blas、lapack的安装及其使用
  10. 单木分割实验之距离聚类(实验五)