欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat数据库连接池数据库密码加密

程序员文章站 2022-07-13 14:57:43
...
1、加密工具类
package com.vajra.security.encrypt;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class CipherEncrypter {
	Cipher ecipher;
	Cipher dcipher;
	byte[] salt = { -87, -101, -56, 50, 86, 53, -29, 3 };

	int iterationCount = 19;
	private static CipherEncrypter cipherEncrypter;

	private CipherEncrypter(String passPhrase) {
		try {
			PBEKeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray());
			SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
					.generateSecret(keySpec);
			this.ecipher = Cipher.getInstance(key.getAlgorithm());
			this.dcipher = Cipher.getInstance(key.getAlgorithm());

			AlgorithmParameterSpec paramSpec = new PBEParameterSpec(this.salt,
					this.iterationCount);

			this.ecipher.init(1, key, paramSpec);
			this.dcipher.init(2, key, paramSpec);
		} catch (InvalidAlgorithmParameterException localInvalidAlgorithmParameterException) {
		} catch (InvalidKeySpecException localInvalidKeySpecException) {
		} catch (NoSuchPaddingException localNoSuchPaddingException) {
		} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
		} catch (InvalidKeyException localInvalidKeyException) {
		}
	}

	private CipherEncrypter() {
		this("sfpay");
	}

	public static CipherEncrypter getInstance() {
		if (cipherEncrypter == null) {
			cipherEncrypter = new CipherEncrypter();
		}
		return cipherEncrypter;
	}

	public static String encrypt(String str) {
		try {
			byte[] utf8 = str.getBytes("UTF8");
			byte[] enc = getInstance().ecipher.doFinal(utf8);
			return new BASE64Encoder().encode(enc);
		} catch (BadPaddingException localBadPaddingException) {
		} catch (IllegalBlockSizeException localIllegalBlockSizeException) {
		} catch (UnsupportedEncodingException localUnsupportedEncodingException) {
		} catch (Exception localException) {
		}
		return null;
	}

	public static String decrypt(String str) {
		try {
			byte[] dec = new BASE64Decoder().decodeBuffer(str);

			byte[] utf8 = getInstance().dcipher.doFinal(dec);

			return new String(utf8, "UTF8");
		} catch (BadPaddingException localBadPaddingException) {
		} catch (IllegalBlockSizeException localIllegalBlockSizeException) {
		} catch (UnsupportedEncodingException localUnsupportedEncodingException) {
		} catch (IOException localIOException) {
		}
		return null;
	}

	public static void main(String[] args) {
		if (args.length != 1)
			return;
		System.out.println("encrypted string:" + encrypt(args[0]));
	}
}

2、Factory中实现数据库密码解密
package com.vajra.security.datasource;

import java.io.ByteArrayInputStream;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;

import com.vajra.security.encrypt.CipherEncrypter;

@SuppressWarnings("rawtypes")
public class VajraBasicDataSourceFactory extends BasicDataSourceFactory {

	protected static final String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";
	protected static final String PROP_DEFAULTREADONLY = "defaultReadOnly";
	protected static final String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";
	protected static final String PROP_DEFAULTCATALOG = "defaultCatalog";
	protected static final String PROP_DRIVERCLASSNAME = "driverClassName";
	protected static final String PROP_MAXACTIVE = "maxActive";
	protected static final String PROP_MAXIDLE = "maxIdle";
	protected static final String PROP_MINIDLE = "minIdle";
	protected static final String PROP_INITIALSIZE = "initialSize";
	protected static final String PROP_MAXWAIT = "maxWait";
	protected static final String PROP_TESTONBORROW = "testOnBorrow";
	protected static final String PROP_TESTONRETURN = "testOnReturn";
	protected static final String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";
	protected static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
	protected static final String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";
	protected static final String PROP_TESTWHILEIDLE = "testWhileIdle";
	protected static final String PROP_PASSWORD = "password";
	protected static final String PROP_URL = "url";
	protected static final String PROP_USERNAME = "username";
	protected static final String PROP_VALIDATIONQUERY = "validationQuery";
	protected static final String PROP_VALIDATIONQUERY_TIMEOUT = "validationQueryTimeout";
	protected static final String PROP_INITCONNECTIONSQLS = "initConnectionSqls";
	protected static final String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";
	protected static final String PROP_REMOVEABANDONED = "removeAbandoned";
	protected static final String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";
	protected static final String PROP_LOGABANDONED = "logAbandoned";
	protected static final String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";
	protected static final String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";
	protected static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";
	protected static final String[] ALL_PROPERTIES = { "defaultAutoCommit",
			"defaultReadOnly", "defaultTransactionIsolation", "defaultCatalog",
			"driverClassName", "maxActive", "maxIdle", "minIdle",
			"initialSize", "maxWait", "testOnBorrow", "testOnReturn",
			"timeBetweenEvictionRunsMillis", "numTestsPerEvictionRun",
			"minEvictableIdleTimeMillis", "testWhileIdle", "password", "url",
			"username", "validationQuery", "validationQueryTimeout",
			"initConnectionSqls", "accessToUnderlyingConnectionAllowed",
			"removeAbandoned", "removeAbandonedTimeout", "logAbandoned",
			"poolPreparedStatements", "maxOpenPreparedStatements",
			"connectionProperties" };

	public Object getObjectInstance(Object obj, Name name, Context nameCtx,
			Hashtable environment) throws Exception {
		if ((obj == null) || (!(obj instanceof Reference))) {
			return null;
		}
		Reference ref = (Reference) obj;
		if (!"javax.sql.DataSource".equals(ref.getClassName())) {
			return null;
		}

		Properties properties = new Properties();
		for (int i = 0; i < ALL_PROPERTIES.length; i++) {
			String propertyName = ALL_PROPERTIES[i];
			RefAddr ra = ref.get(propertyName);
			if (ra != null) {
				String propertyValue = ra.getContent().toString();
				properties.setProperty(propertyName, propertyValue);
			}
		}

		return createDataSource(properties);
	}

	public static DataSource createDataSource(Properties properties)
			throws Exception {
		final BasicDataSource dataSource = new BasicDataSource();
		String value = null;

		value = properties.getProperty("defaultAutoCommit");
		if (value != null) {
			dataSource.setDefaultAutoCommit(Boolean.valueOf(value)
					.booleanValue());
		}

		value = properties.getProperty("defaultReadOnly");
		if (value != null) {
			dataSource
					.setDefaultReadOnly(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("defaultTransactionIsolation");
		if (value != null) {
			int level = -1;
			if ("NONE".equalsIgnoreCase(value)) {
				level = 0;
			} else if ("READ_COMMITTED".equalsIgnoreCase(value)) {
				level = 2;
			} else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {
				level = 1;
			} else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {
				level = 4;
			} else if ("SERIALIZABLE".equalsIgnoreCase(value))
				level = 8;
			else {
				try {
					level = Integer.parseInt(value);
				} catch (NumberFormatException e) {
					System.err
							.println("Could not parse defaultTransactionIsolation: "
									+ value);
					System.err
							.println("WARNING: defaultTransactionIsolation not set");
					System.err
							.println("using default value of database driver");

					level = -1;
				}
			}
			dataSource.setDefaultTransactionIsolation(level);
		}

		value = properties.getProperty("defaultCatalog");
		if (value != null) {
			dataSource.setDefaultCatalog(value);
		}

		value = properties.getProperty("driverClassName");
		if (value != null) {
			dataSource.setDriverClassName(value);
		}

		value = properties.getProperty("maxActive");
		if (value != null) {
			dataSource.setMaxActive(Integer.parseInt(value));
		}

		value = properties.getProperty("maxIdle");
		if (value != null) {
			dataSource.setMaxIdle(Integer.parseInt(value));
		}

		value = properties.getProperty("minIdle");
		if (value != null) {
			dataSource.setMinIdle(Integer.parseInt(value));
		}

		value = properties.getProperty("initialSize");
		if (value != null) {
			dataSource.setInitialSize(Integer.parseInt(value));
		}

		value = properties.getProperty("maxWait");
		if (value != null) {
			dataSource.setMaxWait(Long.parseLong(value));
		}

		value = properties.getProperty("testOnBorrow");
		if (value != null) {
			dataSource.setTestOnBorrow(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("testOnReturn");
		if (value != null) {
			dataSource.setTestOnReturn(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("timeBetweenEvictionRunsMillis");
		if (value != null) {
			dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(value));
		}

		value = properties.getProperty("numTestsPerEvictionRun");
		if (value != null) {
			dataSource.setNumTestsPerEvictionRun(Integer.parseInt(value));
		}

		value = properties.getProperty("minEvictableIdleTimeMillis");
		if (value != null) {
			dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(value));
		}

		value = properties.getProperty("testWhileIdle");
		if (value != null) {
			dataSource.setTestWhileIdle(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("password");
		if (value != null) {
			dataSource.setPassword(CipherEncrypter.decrypt(value.trim()));
		}

		value = properties.getProperty("url");
		if (value != null) {
			dataSource.setUrl(value);
		}

		value = properties.getProperty("username");
		if (value != null) {
			dataSource.setUsername(value.trim());
		}

		value = properties.getProperty("validationQuery");
		if (value != null) {
			dataSource.setValidationQuery(value);
		}

		value = properties.getProperty("validationQueryTimeout");
		if (value != null) {
			dataSource.setValidationQueryTimeout(Integer.parseInt(value));
		}

		value = properties.getProperty("accessToUnderlyingConnectionAllowed");
		if (value != null) {
			dataSource.setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(
					value).booleanValue());
		}

		value = properties.getProperty("removeAbandoned");
		if (value != null) {
			dataSource
					.setRemoveAbandoned(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("removeAbandonedTimeout");
		if (value != null) {
			dataSource.setRemoveAbandonedTimeout(Integer.parseInt(value));
		}

		value = properties.getProperty("logAbandoned");
		if (value != null) {
			dataSource.setLogAbandoned(Boolean.valueOf(value).booleanValue());
		}

		value = properties.getProperty("poolPreparedStatements");
		if (value != null) {
			dataSource.setPoolPreparedStatements(Boolean.valueOf(value)
					.booleanValue());
		}

		value = properties.getProperty("maxOpenPreparedStatements");
		if (value != null) {
			dataSource.setMaxOpenPreparedStatements(Integer.parseInt(value));
		}

		value = properties.getProperty("initConnectionSqls");
		if (value != null) {
			StringTokenizer tokenizer = new StringTokenizer(value, ";");
			dataSource.setConnectionInitSqls(Collections.list(tokenizer));
		}

		value = properties.getProperty("connectionProperties");
		if (value != null) {
			Properties p = getProperties(value);
			Enumeration e = p.propertyNames();
			while (e.hasMoreElements()) {
				String propertyName = (String) e.nextElement();
				dataSource.addConnectionProperty(propertyName,
						p.getProperty(propertyName));
			}

		}

		if (dataSource.getInitialSize() > 0) {
			dataSource.getLogWriter();
		}

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				try {
					dataSource.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		});

		return dataSource;
	}

	protected static Properties getProperties(String propText) throws Exception {
		Properties p = new Properties();
		if (propText != null) {
			p.load(new ByteArrayInputStream(propText.replace(';', '\n').getBytes()));
		}
		return p;
	}

}

3、将以上两个类打包(vajra-dbsecure.jar),并指定Main入口类
D:\>java -jar vajra-dbsecure.jar 1234567
encrypted string :L9+rt2kMEHo=

4、tomcat全局数据源中使用加密后的数据库密码
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="50" maxIdle="20" maxOpenPreparedStatements="100" maxWait="10000" name="jdbc/yxzxuserDS" password="L9+rt2kMEHo=" poolPreparedStatements="true" type="javax.sql.DataSource" url="jdbc:mysql://192.168.2.102:3306/testdb?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false" username="appuser" validationQuery="SELECT 1" factory="com.vajra.security.datasource.VajraBasicDataSourceFactory"/>
相关标签: java tomcat

上一篇: JAVA NIO AIO

下一篇: Netty安全性