1、加密工具类
class="java">
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&useUnicode=true&characterEncoding=UTF-8&useSSL=false" username="appuser" validationQuery="SELECT 1" factory="com.vajra.security.datasource.VajraBasicDataSourceFactory"/>