如何修改proxool源码, 配置对连接的数据库密码加密

如何修改proxool源码, 配置对连接的数据库密码加密,第1张

proxool是不错的连接池,可是配置文件里数据库的密码默认是明文,感觉有点裸奔的感觉。想修改成密文。思路就是把datasource里的class设置为自己写的类,这个类继承org.logicalcobwebs.proxool.ProxoolDataSource;如:<bean id="dataSource" class="com.hclm.agency.db.DataSource">;

在这个类里取出密码的密文,解密然后重置proxool的密码和url。上代码:

/**

* 重写org.logicalcobwebs.proxool.ProxoolDataSource

* 重置数据库密码为明文

* @author Administrator

*

*/

public class DataSource extends org.logicalcobwebs.proxool.ProxoolDataSource {

/**

* 重置数据库链接信息为明文

*/

public void setPassword(String mi) {

super.setPassword(mi)

String passWord = DesDecode(mi)

super.setPassword(passWord)

String url = reSetUrl(super.getDriverUrl(), super.getPassword())

super.setDriverUrl(url)

}

/*替换url的密码为明文*/

public String reSetUrl(String url, String pwd) {

int begin = url.indexOf('/')

int end = url.indexOf('@')

String url2 = url.substring(0, begin + 1) + pwd + url.substring(end)

return url2

}

public String getPassword() {

return super.getPassword()

}

/* 根据数据库配置文件密码密文得到明文 */

public String DesDecode(String mi) {

DESUtil des = new DESUtil()

des.getKey("HUACAIKEYG")

String strDes = des.getDesString(mi)

return strDes

}

}

加密的类自己写就行了:

上示例:

package com.hclm.agency.web.util

/*

字符串 DESede(3DES) 加密

*/

import java.io.BufferedReader

import java.io.InputStreamReader

import java.io.UnsupportedEncodingException

import java.security.*

import javax.crypto.*

import javax.crypto.spec.SecretKeySpec

import sun.misc.BASE64Encoder

public class ThreeDes {

private static final String Algorithm = "DESede"//定义 加密算法,可用 DES,DESede,Blowfish

//keybyte为加密密钥,长度为24字节

//src为被加密的数据缓冲区(源)

public static byte[] encryptMode(byte[] keybyte, byte[] src) {

try {

//生成密钥

SecretKey deskey = new SecretKeySpec(keybyte, Algorithm)

//加密

Cipher c1 = Cipher.getInstance(Algorithm)

c1.init(Cipher.ENCRYPT_MODE, deskey)

return c1.doFinal(src)

} catch (java.security.NoSuchAlgorithmException e1) {

e1.printStackTrace()

} catch (javax.crypto.NoSuchPaddingException e2) {

e2.printStackTrace()

} catch (java.lang.Exception e3) {

e3.printStackTrace()

}

return null

}

//keybyte为加密密钥,长度为24字节

//src为加密后的缓冲区

public static byte[] decryptMode(byte[] keybyte, byte[] src) {

try {

//生成密钥

SecretKey deskey = new SecretKeySpec(keybyte, Algorithm)

//解密

//Cipher c1 = Cipher.getInstance(Algorithm)

Cipher c1 = Cipher.getInstance("DESede/ECB/PKCS5Padding")

c1.init(Cipher.DECRYPT_MODE, deskey)

return c1.doFinal(src)

} catch (java.security.NoSuchAlgorithmException e1) {

e1.printStackTrace()

} catch (javax.crypto.NoSuchPaddingException e2) {

e2.printStackTrace()

} catch (java.lang.Exception e3) {

e3.printStackTrace()

}

return null

}

//转换成十六进制字符串

public static String byte2hex(byte[] b) {

String hs=""

String stmp=""

for (int n=0n<b.lengthn++) {

stmp=(java.lang.Integer.toHexString(b[n] &0XFF))

if (stmp.length()==1) hs=hs+"0"+stmp

else hs=hs+stmp

if (n<b.length-1) hs=hs+":"

}

return hs.toUpperCase()

}

public static void main(String[] args)

{

BufferedReader reader

String input

int i=0

try{

while(true){

if(i>0){

System.out.println("<<结束请输入exit>>")

}

System.out.println("请输入密码明文:")

reader = new BufferedReader(new InputStreamReader(System.in))

input= reader.readLine()

// 处理控制台命令

if (input.equals("exit")){

break

}else if(input == null||input.length()<7) {

System.out.println("明文字符串不能为空并且长度需要大于6")

continue

}else {

i++

input = input.trim()

//添加新安全算法,如果用JCE就要把它添加进去

Security.addProvider(new com.sun.crypto.provider.SunJCE())

final byte[] keyBytes = {0x11, 0x22, 0x4F, 0x58, (byte)0x88, 0x10, 0x40, 0x38

, 0x28, 0x25, 0x79, 0x51, (byte)0xCB, (byte)0xDD, 0x55, 0x66

, 0x77, 0x29, 0x74, (byte)0x98, 0x30, 0x40, 0x36, (byte)0xE2}//24字节的密钥

try {

String szSrc = input

System.out.println("加密前的字符串:" + szSrc)

byte[] encoded = encryptMode(keyBytes, szSrc.getBytes())

BASE64Encoder base64en = new BASE64Encoder()

System.out.println("加密后的字符串:" + Base64.encode(encoded))

byte[] srcBytes = decryptMode(keyBytes, Base64.decode(Base64.encode(encoded)))

// System.out.println("解密后的字符串:" + (new String(srcBytes)))

} catch (Exception e) {

// TODO Auto-generated catch block dCqB6+nmwnXOECa05SO3tA==

e.printStackTrace()

}

}

}

}catch(Exception e){

e.printStackTrace()

}

}

}

问题解决思路:将配置文件用户相关的信息(例如:密码)进行加密使其以密文形式存在,进行初始化连接池的时候进行解密 *** 作,达到成功创建连接池的目的。Tomcat默认使用DBCP连接池(基于common-pool的一种连接池实现),可在下载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,本例中使用加密解密模块比较简单只是用来说明问题,密文为明文的十六进制串。publicclassEncode{//编码-普通字符串转为十六进制字符串publicstaticStringencode(Stringpassword){Stringresult=“”byte[]psd=password.getBytes()for(inti=0ipassword696e65743231urljdbc:oracle:thin:@127.0.0.1:1521:orcldriverClassNameoracle.jdbc.driver.OracleDriverusernamewanfang4.将修改后的BasicDataSourceFactory.java和新添加的Encode.java编译后的class类文件重新打包进commons-dbcp-1.4.jar,将该包拷贝进tomcat下的common/lib目录中,重启tomcat。此时tomcat下部署的应用在连接数据源的时候都可以在不暴露密码明文的情况下进行连接。转载,仅供参考。

数据库账号密码加密详解及实例

数据库中经常有对数据库账号密码的加密,但是碰到一个问题,在使用UserService对密码进行加密的时候,spring security 也是需要进行同步配置的,因为spring security 中验证的加密方式是单独配置的。如下:

<authentication-manager>

<authentication-provider user-service-ref="userDetailService">

<password-encoder ref="passwordEncoder" />

</authentication-provider>

</authentication-manager>

<beans:bean class="com.sapphire.security.MyPasswordEncoder" id="passwordEncoder">

<beans:constructor-arg value="md5"></beans:constructor-arg>

</beans:bean>

如上述配置文件所示,passwordEncoder才是在spring security对账号加密校验的地方。

spring security在拦截之后,会首先对用户进行查找,通过自己定义的userDetailService来找到对应的用户,然后由框架进行密码的匹配验证。

从userDetailService得到user以后,就会进入到DaoAuthenticationProvider中,这是框架中定义的 ,然后跳入其中的authenticate方法中。

该方法会进行两个检查,分别是

* preAuthenticationChecks : 主要进行的是对用户是否过期等信息的校验,调用的方法在userDetail中有定义的。

* additionalAuthenticationChecks : 这个就是用户名密码验证的过程了。

而PasswordEncoder是我们xml中注入的bean,所以了,我们调用的则是我们自己完成的passwordEncoder

public class MyPasswordEncoder extends MessageDigestPasswordEncoder {

public MyPasswordEncoder(String algorithm) {

super(algorithm)

}

@Override

public boolean isPasswordValid(String encPass, String rawPass, Object salt) {

return encPass.equals(DigestUtils.md5DigestAsHex(rawPass.getBytes()))

}

}

这是我对其实现的一个简单版本,调用的就是spring自带的加密算法,很简单了,当然也可以使用复杂的加密方法,这个就靠自己了

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9673111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存