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

标签: tomcat 数据库 数据库 | 发表时间:2019-03-06 23:08 | 作者:log_cd
出处:https://www.iteye.com
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"/>


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [tomcat 数据库 数据库] 推荐:

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

- - Java - 编程语言 - ITeye博客
2、Factory中实现数据库密码解密. 3、将以上两个类打包(vajra-dbsecure.jar),并指定Main入口类. 4、tomcat全局数据源中使用加密后的数据库密码. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

数据库sharding

- - 数据库 - ITeye博客
当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确地知道需要访问的数据表以及查询参数,借助这些信息可以直接定位到目标shard上,而不必像框架那样需要对SQL进行解析然后再依据配置的规则进行路由. 另一个优势是不会受ORM框架的制约.

数据库索引

- - CSDN博客推荐文章
索引是由用户创建的、能够被修改和删除的、实际存储于数据库中的物理存在;创建索引的目的是使用户能够从整体内容直接查找到某个特定部分的内容. 一般来说,索引能够提高查询,但是会增加额外的空间消耗,并且降低删除、插入和修改速度. 1.聚集索引:表数据按照索引的顺序来存储的. 2.非聚集索引:表数据存储顺序与索引顺序无关.

数据库事务

- - 数据库 - ITeye博客
事务传播发生在类似以下情形:. 假设methodB的配置是:. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在事务里,那么methodB重新建立一个事务运行. 如果methodA在事务里,那么methodB也在这个事务中运行. 如果methodA不在是事务里,那么methodB在非事务中运行.

数据库优化

- - 数据库 - ITeye博客
程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点: . a) SQL的使用规范: .   i.尽量避免大事务操作,慎用holdlock子句,提高系统并发能力.   ii.尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接.   iii.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作.

数据库调优

- - 数据库 - ITeye博客
1、1、调整数据结构的设计. 这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等. 这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构.

MySQL数据库的修复

- Xin - 博客园-首页原创精华区
找到mysql的安装目录的bin/myisamchk工具,在命令行中输入:. 然后myisamchk 工具会帮助你恢复数据表的索引. 好象也不用重新启动mysql,问题就解决了. 当你试图修复一个被破坏的表的问题时,有三种修复类型. 如果你得到一个错误信息指出一个临时文件不能建立,删除信息所指出的文件并再试一次--这通常是上一次修复操作遗留下来的.

Oracle 发布 NoSQL 数据库

- 冷月 - 博客园新闻频道
  Oracle 作为全球最大的关系型数据库提供商,在其产品链条中,也加入了 NoSQL 数据库这一环,而且这个新的数据库名字很霸气,就叫 NoSQL Database,想起了当年新浪微博更换 weibo.com 域名之时的一个笑话:. 原来有三家人做面包,张三家的面包叫三张牌面包,李四家的牌子叫李四牌面包,王五家出品的是王五牌面包,而突然有一天,张三家的面包改名了,叫面包牌面包.

WineHQ 数据库泄漏

- gnawux - LinuxTOY
运行于 *Nix 之上的开源跨平台 Win32 API 兼容层 WineHQ 的 AppDB 和 Bugzilla 数据库被黑客攻击. CodeWeavers CEO Jeremy 在信中提到黑客利用某种方式获取了 WineHQ 的 AppDB 和 Bugzilla 的访问,并且下载了完整数据库文件.