数据源c3p0连接 密码加密

(一)背景

 最近一个项目的数据源用的dbcp,dbcp数据源的连接密码是加密过得,主要的加密操作是之前同事做的,查了很久,他是修改了dbcp的源码,修改了BasicDataSource类里面的createConnectionFactory()方法,主要是在里面对加密的密码进行了解密,再创建连接。

String pwd = reset(password);
		if (pwd != null)
			connectionProperties.put("password", pwd);
		else
			log("DBCP DataSource configured without a 'password'");

然后,我们只要用他重新打包发布的dbcp jar包就能用加过密的密码创建数据库连接。

现在的情况是,我想换数据源,但是新的数据源不想修改源码,同时还是使用加密的密码做数据库连接,这是为了防止数据库泄露(虽然说这种方式,是防君子,不防小人)


(二)分析

通过上面的了解,可以修改dbcp的源码对加密的密码进行解密,然后创建连接,那么是不是也可以在不修改源码的情况下,拦截源码中创建连接时的setPassword()方法,解密后再设置。那么,应该拦截哪个方法呢?或者说继承

(三)测试

1.配置文件修改

  
          
              
                ${${env}.boms.jdbc.username}  
                ${${env}.boms.jdbc.password}  
              
          
      
    
     
        
        
          
       
        
      
    

2.PropertiesEncryptFactoryBean(加密类) 

public class PropertiesEncryptFactoryBean implements FactoryBean{

	 private Properties properties;  
     
	    public Object getObject() throws Exception {  
	        return getProperties();  
	    }  
	  
	    public Class getObjectType() {  
	        return java.util.Properties.class;  
	    }  
	  
	    public boolean isSingleton() {  
	        return true;  
	    }  
	  
	    public Properties getProperties() {  
	        return properties;  
	    }  
	  
	    public void setProperties(Properties inProperties) {  
	        this.properties = inProperties;  
	        String originalUsername = properties.getProperty("user");  
	        String originalPassword = properties.getProperty("password");  
	        //if (originalUsername != null){  
	        //    String newUsername = deEncryptUsername(originalUsername);  
	            properties.put("user", originalUsername);  
	       // }  
	        if (originalPassword != null){  
	            String newPassword;
				try {
					newPassword = reset(originalPassword);
					properties.put("password", newPassword);  
				} catch (InvalidKeyException | SQLNestedException
						| NoSuchAlgorithmException | NoSuchPaddingException
						| IllegalBlockSizeException | BadPaddingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}  
	            
	        }  
	    }  
	      
	    private String deEncryptUsername(String originalUsername){  
	        return deEncryptString(originalUsername);  
	    }  
	      
	    private String deEncryptPassword(String originalPassword){  
	        return deEncryptString(originalPassword);  
	    }  
	    //简单加密  
	    private String deEncryptString(String originalString){  
	        StringBuilder newString = new StringBuilder();  
	        for (int i = 0; i < originalString.length(); i++) {  
	            char eachChar= originalString.charAt(i);  
	            char newChar = (char)(eachChar + i);  
	            newString.append(newChar);  
	        }  
	        return newString.toString();  
	    }  
	    
	    private String reset(String secret)
				throws SQLNestedException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException
			{
				byte decode[];
				byte kbytes[] = "TjE5MGQ5".getBytes();
				SecretKeySpec key = new SecretKeySpec(kbytes, "Blowfish");
				BigInteger n = new BigInteger(secret, 16);
				byte encoding[] = n.toByteArray();
				Cipher cipher = Cipher.getInstance("Blowfish");
				cipher.init(2, key);
				decode = cipher.doFinal(encoding);
				return new String(decode);
			}
}

这里使用的加密解密算法是Cipher,因为我们需要的加密解密的密码是一样的,所以需要使用对称的加密解密算法。

测试下来,这样是可以的。

(四)总结

这种方式是主要是利用了spring加载顺序,因为在加载c3p0加载之前先对配置文件中的密码进行相应的解密,并且注入到属性password中,这样在创建c3p0连接的时候,用的密码就是明文密码了。


这里的数据源安全机制感觉还不是很靠谱,下面需要试验更改源码。

你可能感兴趣的:(数据源学习)