Tomcat数据源连接池加密

jopen 10年前

我们在使用Tomcat数据库连接池的时候都是明文存储数据库用户名和密码的,例如:

<Resource name="ODS" type="javax.sql.DataSource"   driverClassName="oracle.jdbc.driver.OracleDriver"   url="jdbc:oracle:thin:@192.168.1.1:1521:dbid"   username="oracle"   password="oracle"   maxIdle="4"   maxActive="6"   maxWait="5000" />
如果我们不想让数据库的密码暴露在web容器中怎么办呢?写一个类继承org.apache.commons.dbcp.BasicDataSourceFactory,然后指定factory=”*.EncryptedDataSourceFactory”为你的自定义类,下面是相关代码:

package net.uni.ap.jdbc;  import java.util.Enumeration;  import java.util.Hashtable;  import javax.naming.Context;  import javax.naming.Name;  import javax.naming.RefAddr;  import javax.naming.Reference;  import javax.naming.StringRefAddr;  import org.apache.commons.dbcp.BasicDataSourceFactory;  import com.fesco.fws.utils.TeaUtil;  /**   *    * @author sunwill   *    */  public class EncryptedDataSourceFactory extends BasicDataSourceFactory {   public Object getObjectInstance(Object obj, Name name, Context nameCtx,   Hashtable environment) throws Exception {   if (obj instanceof Reference) {   setUsername((Reference) obj);   setPassword((Reference) obj);   }   return super.getObjectInstance(obj, name, nameCtx, environment);   }  private void setUsername(Reference ref) throws Exception {   findDecryptAndReplace("username", ref);   }  private void setPassword(Reference ref) throws Exception {   findDecryptAndReplace("password", ref);   }  private void findDecryptAndReplace(String refType, Reference ref)   throws Exception {   int idx = find(refType, ref);   String decrypted = decrypt(idx, ref);   replace(idx, refType, decrypted, ref);   }  private void replace(int idx, String refType, String newValue, Reference ref)   throws Exception {   ref.remove(idx);   ref.add(idx, new StringRefAddr(refType, newValue));   }  private String decrypt(int idx, Reference ref) throws Exception {   return TeaUtil.decryptByTea(ref.get(idx).getContent().toString());   }  private int find(String addrType, Reference ref) throws Exception {   Enumeration enu = ref.getAll();   for (int i = 0; enu.hasMoreElements(); i++) {   RefAddr addr = (RefAddr) enu.nextElement();   if (addr.getType().compareTo(addrType) == 0) {   return i;   }   }   throw new Exception("The \"" + addrType   + "\" name/value pair was not found"   + " in the Reference object. The reference Object is" + " "   + ref.toString());   }}
其中红色的地方是你的数据库密码解密方法,当然对应的也要有加密算法,加密后的串放到连接池的地方:

<Context path="">   <Resource name="ODS" type="javax.sql.DataSource"   driverClassName="oracle.jdbc.driver.OracleDriver"   factory="net.uni.ap.jdbc.EncryptedDataSourceFactory"   url="jdbc:oracle:thin:@192.168.1.1:1521:sid"   username="oracle"   password="C65BD76C4CED33C446B289F64CAFACC5"   maxIdle="4"   maxActive="6"   maxWait="5000" />  </Context>