From eaf0ccb80bc7359842417af30d44ee58353259cb Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 1 Sep 2012 09:01:59 +0800 Subject: [PATCH] refactor ConfigFilter --- .../druid/filter/config/ConfigFilter.java | 136 +++------------- .../druid/filter/config/ConfigTools.java | 154 +++++++++++++++--- .../resources/bvt/config/config-2.properties | 2 +- 3 files changed, 156 insertions(+), 136 deletions(-) diff --git a/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java b/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java index 230fd4934b..d90503f84c 100644 --- a/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java +++ b/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java @@ -15,28 +15,20 @@ */ package com.alibaba.druid.filter.config; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; -import java.security.KeyFactory; import java.security.PublicKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; -import java.security.spec.X509EncodedKeySpec; import java.sql.SQLException; import java.util.Properties; -import javax.crypto.Cipher; - import com.alibaba.druid.filter.FilterAdapter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import com.alibaba.druid.proxy.jdbc.DataSourceProxy; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; -import com.alibaba.druid.util.Base64; import com.alibaba.druid.util.JdbcUtils; /** @@ -50,7 +42,7 @@ import com.alibaba.druid.util.JdbcUtils; * //启用config filter * dataSource.setFilters("config"); * //使用RSA解密(使用默认密钥) - * dataSource.setConnectionPropertise("config.decrypt=RSA"); + * dataSource.setConnectionPropertise("config.decrypt=true"); * dataSource.setPassword("加密的密文"); * * [远程配置文件] @@ -67,7 +59,7 @@ import com.alibaba.druid.util.JdbcUtils; * <property name="password" value="加密的密文" /> * <!-- 其他的属性设置 --> * <property name="filters" value="config" /> - * <property name="connectionProperties" value="config.decrypt=RSA" /> + * <property name="connectionProperties" value="config.decrypt=true" /> * </bean> * * [Spring的配置远程配置文件] @@ -78,7 +70,7 @@ import com.alibaba.druid.util.JdbcUtils; * </bean> * * [使用系统属性配置远程文件] - * java -Ddruid.config.file=file:/home/test/my.properties ... + * java -Ddruid.config.file=file:///home/test/my.properties ... * * 远程配置文件格式: * 1. 其他的属性KEY请查看 @see com.alibaba.druid.pool.DruidDataSourceFactory @@ -87,29 +79,26 @@ import com.alibaba.druid.util.JdbcUtils; * config.file=http://xxxxx(http://开头或者file:开头) * * #RSA解密, Key不指定, 使用默认的 - * config.decrypt=RSA + * config.decrypt=true * config.decrypt.key=密钥字符串 * config.decrypt.keyFile=密钥文件路径 * config.decrypt.x509File=证书路径 * * + * * @author Jonas Yang */ public class ConfigFilter extends FilterAdapter { - private static Log LOG = LogFactory.getLog(ConfigFilter.class); + private static Log LOG = LogFactory.getLog(ConfigFilter.class); - public static final String CONFIG_FILE = "config.file"; + public static final String CONFIG_FILE = "config.file"; + public static final String CONFIG_DECRYPT = "config.decrypt"; + public static final String CONFIG_KEY = "config.decrypt.key"; + public static final String CONFIG_KEY_FILE = "config.decrypt.keyFile"; + public static final String CONFIG_X509_FILE = "config.decrypt.x509File"; - public static final String CONFIG_DECRYPT = "config.decrypt"; - - public static final String SYS_PROP_CONFIG_FILE = "druid.config.file"; - - public static final String KEY = "config.decrypt.key"; - public static final String KEY_FILE = "config.decrypt.keyFile"; - public static final String X509_FILE = "config.decrypt.x509File"; - - public static final String DEFAULT_PUBLIC_KEY_STRING = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKHGwq7q2RmwuRgKxBypQHw0mYu4BQZ3eMsTrdK8E6igRcxsobUC7uT0SoxIjl1WveWniCASejoQtn/BY6hVKWsCAwEAAQ=="; + public static final String SYS_PROP_CONFIG_FILE = "druid.config.file"; public ConfigFilter(){ } @@ -202,10 +191,7 @@ public class ConfigFilter extends FilterAdapter { } PublicKey publicKey = getPublicKey(dataSource.getConnectProperties(), info); - - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, publicKey); - String passwordPlainText = decrypt(cipher, encryptedPassword); + String passwordPlainText = ConfigTools.decrypt(publicKey, encryptedPassword); if (info != null) { info.setProperty(DruidDataSourceFactory.PROP_PASSWORD, passwordPlainText); @@ -217,110 +203,32 @@ public class ConfigFilter extends FilterAdapter { } } - protected String decrypt(Cipher cipher, String cipherString) throws Exception { - if (cipherString == null || cipherString.length() == 0) { - return cipherString; - } - - byte[] cipherBytes = Base64.base64ToByteArray(cipherString); - byte[] plainBytes = cipher.doFinal(cipherBytes); - - return new String(plainBytes); - } - public PublicKey getPublicKey(Properties connectinProperties, Properties configFileProperties) { - String key = connectinProperties.getProperty(KEY); - String publicKeyFile = connectinProperties.getProperty(KEY_FILE); - String x509File = connectinProperties.getProperty(X509_FILE); + String key = connectinProperties.getProperty(CONFIG_KEY); + String publicKeyFile = connectinProperties.getProperty(CONFIG_KEY_FILE); + String x509File = connectinProperties.getProperty(CONFIG_X509_FILE); if (connectinProperties != null && (key == null || key.length() == 0)) { - key = connectinProperties.getProperty(KEY); + key = connectinProperties.getProperty(CONFIG_KEY); } if (connectinProperties != null && (publicKeyFile == null || publicKeyFile.length() == 0)) { - publicKeyFile = connectinProperties.getProperty(KEY_FILE); + publicKeyFile = connectinProperties.getProperty(CONFIG_KEY_FILE); } if (connectinProperties != null && (x509File == null || x509File.length() == 0)) { - x509File = connectinProperties.getProperty(X509_FILE); + x509File = connectinProperties.getProperty(CONFIG_X509_FILE); } if (publicKeyFile != null) { - if (LOG.isDebugEnabled()) { - LOG.debug("Decrypt by public key file"); - } - return getPublicKeyByPublicKeyFile(publicKeyFile); + return ConfigTools.getPublicKeyByPublicKeyFile(publicKeyFile); } if (x509File != null) { - if (LOG.isDebugEnabled()) { - LOG.debug("Decrypt by X509 file"); - } - return getPublicKeyByX509(x509File); + return ConfigTools.getPublicKeyByX509(x509File); } - return getPublicKeyByString(key); - } - - public PublicKey getPublicKeyByX509(String x509File) { - if (x509File == null || x509File.length() == 0) { - return getPublicKeyByString(null); - } - - FileInputStream in = null; - try { - in = new FileInputStream(x509File); - - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - Certificate cer = factory.generateCertificate(in); - return cer.getPublicKey(); - } catch (Exception e) { - throw new IllegalArgumentException("Failed to get public key", e); - } finally { - JdbcUtils.close(in); - } - } - - public PublicKey getPublicKeyByPublicKeyFile(String publicKeyFile) { - if (publicKeyFile == null || publicKeyFile.length() == 0) { - return getPublicKeyByString(null); - } - - FileInputStream in = null; - try { - in = new FileInputStream(publicKeyFile); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int len = 0; - byte[] b = new byte[512 / 8]; - while ((len = in.read(b)) != -1) { - out.write(b, 0, len); - } - - byte[] publicKeyBytes = out.toByteArray(); - X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes); - KeyFactory factory = KeyFactory.getInstance("RSA"); - return factory.generatePublic(spec); - } catch (Exception e) { - throw new IllegalArgumentException("Failed to get public key", e); - } finally { - JdbcUtils.close(in); - } - } - - public PublicKey getPublicKeyByString(String publicKeyString) { - if (publicKeyString == null || publicKeyString.length() == 0) { - publicKeyString = DEFAULT_PUBLIC_KEY_STRING; - } - - try { - byte[] publicKeyBytes = Base64.base64ToByteArray(publicKeyString); - X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes); - - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePublic(x509KeySpec); - } catch (Exception e) { - throw new IllegalArgumentException("Failed to get public key", e); - } + return ConfigTools.getPublicKey(key); } public Properties loadConfig(String filePath) { diff --git a/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java b/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java index af892895a5..b3858a2d18 100644 --- a/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java +++ b/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java @@ -10,18 +10,22 @@ import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import com.alibaba.druid.util.Base64; +import com.alibaba.druid.util.JdbcUtils; public class ConfigTools { private static final String DEFAULT_PRIVATE_KEY_STRING = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAocbCrurZGbC5GArEHKlAfDSZi7gFBnd4yxOt0rwTqKBFzGyhtQLu5PRKjEiOXVa95aeIIBJ6OhC2f8FjqFUpawIDAQABAkAPejKaBYHrwUqUEEOe8lpnB6lBAsQIUFnQI/vXU4MV+MhIzW0BLVZCiarIQqUXeOhThVWXKFt8GxCykrrUsQ6BAiEA4vMVxEHBovz1di3aozzFvSMdsjTcYRRo82hS5Ru2/OECIQC2fAPoXixVTVY7bNMeuxCP4954ZkXp7fEPDINCjcQDywIgcc8XLkkPcs3Jxk7uYofaXaPbg39wuJpEmzPIxi3k0OECIGubmdpOnin3HuCP/bbjbJLNNoUdGiEmFL5hDI4UdwAdAiEAtcAwbm08bKN7pwwvyqaCBC//VnEWaq39DCzxr+Z2EIk="; - - private static boolean isEnd = false; + public static final String DEFAULT_PUBLIC_KEY_STRING = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKHGwq7q2RmwuRgKxBypQHw0mYu4BQZ3eMsTrdK8E6igRcxsobUC7uT0SoxIjl1WveWniCASejoQtn/BY6hVKWsCAwEAAQ=="; public static void main(String[] args) { System.out.println("**************************************"); @@ -30,29 +34,111 @@ public class ConfigTools { System.out.println("* *"); System.out.println("**************************************"); - while (!isEnd) { - System.out.println(); - System.out.println("RSA 选项: "); - System.out.println("1. 通过私钥加密"); - System.out.println("2. 创建 RSA 密钥"); - System.out.println("3. 退出"); - System.out.println(""); + System.out.println(); + System.out.println("RSA 选项: "); + System.out.println("1. 通过私钥加密"); + System.out.println("2. 创建 RSA 密钥"); + System.out.println("3. 退出"); + System.out.println(""); - String input = System.console().readLine("[RSA]请输入选项: "); - input = input.toLowerCase(); + String input = System.console().readLine("[RSA]请输入选项: "); + input = input.toLowerCase(); - if ("1".equals(input)) { - encrypt(); - } else if ("2".equals(input)) { - generateKeys(); - } else if ("q".equals(input) || "3".equals(input)) { - System.exit(0); - } else { - System.err.println("不是一个合法的输入."); - } + if ("1".equals(input)) { + encrypt(); + } else if ("2".equals(input)) { + generateKeys(); + } else if ("q".equals(input) || "3".equals(input)) { + System.exit(0); + } else { + System.err.println("不是一个合法的输入."); } } + + public static String decrypt(String cipherText) throws Exception { + return decrypt((String) null, cipherText); + } + + public static String decrypt(String publicKeyText, String cipherText) throws Exception { + PublicKey publicKey = getPublicKey(publicKeyText); + + return decrypt(publicKey, cipherText); + } + + public static PublicKey getPublicKeyByX509(String x509File) { + if (x509File == null || x509File.length() == 0) { + return ConfigTools.getPublicKey(null); + } + FileInputStream in = null; + try { + in = new FileInputStream(x509File); + + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + Certificate cer = factory.generateCertificate(in); + return cer.getPublicKey(); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to get public key", e); + } finally { + JdbcUtils.close(in); + } + } + + public static PublicKey getPublicKey(String publicKeyText) { + if (publicKeyText == null || publicKeyText.length() == 0) { + publicKeyText = ConfigTools.DEFAULT_PUBLIC_KEY_STRING; + } + + try { + byte[] publicKeyBytes = Base64.base64ToByteArray(publicKeyText); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes); + + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(x509KeySpec); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to get public key", e); + } + } + + public static PublicKey getPublicKeyByPublicKeyFile(String publicKeyFile) { + if (publicKeyFile == null || publicKeyFile.length() == 0) { + return ConfigTools.getPublicKey(null); + } + + FileInputStream in = null; + try { + in = new FileInputStream(publicKeyFile); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int len = 0; + byte[] b = new byte[512 / 8]; + while ((len = in.read(b)) != -1) { + out.write(b, 0, len); + } + + byte[] publicKeyBytes = out.toByteArray(); + X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + return factory.generatePublic(spec); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to get public key", e); + } finally { + JdbcUtils.close(in); + } + } + + public static String decrypt(PublicKey publicKey, String cipherText) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + + if (cipherText == null || cipherText.length() == 0) { + return cipherText; + } + + byte[] cipherBytes = Base64.base64ToByteArray(cipherText); + byte[] plainBytes = cipher.doFinal(cipherBytes); + + return new String(plainBytes); + } private static void encrypt() { System.out.println("注意: 如果输入的不是该工具生成的私钥, 请转成PKCS#8格式, 使用下面命令"); @@ -82,7 +168,6 @@ public class ConfigTools { byte[] encryptedBytes = cipher.doFinal(plainString.getBytes()); String encryptedString = Base64.byteArrayToBase64(encryptedBytes); - ; System.out.println("请记住以下的密文, 长度为[" + encryptedString.length() + "]."); System.out.println(); @@ -93,6 +178,32 @@ public class ConfigTools { e.printStackTrace(); } } + + public static String encrypt(String plainText) throws Exception { + return encrypt((String) null, plainText); + } + + public static String encrypt(String key, String plainText) throws Exception { + if (key == null) { + key = DEFAULT_PRIVATE_KEY_STRING; + } + + byte[] keyBytes = Base64.base64ToByteArray(key); + return encrypt(keyBytes, plainText); + } + + public static String encrypt(byte[] keyBytes, String plainText) throws Exception { + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory factory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = factory.generatePrivate(spec); + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + + byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8")); + String encryptedString = Base64.byteArrayToBase64(encryptedBytes); + + return encryptedString; + } private static byte[] getPrivateKeyFromFile(String filePath) throws IOException { if (!new File(filePath).exists()) { @@ -170,4 +281,5 @@ public class ConfigTools { } } } + } diff --git a/src/test/resources/bvt/config/config-2.properties b/src/test/resources/bvt/config/config-2.properties index 87ccd7e735..10540d6622 100644 --- a/src/test/resources/bvt/config/config-2.properties +++ b/src/test/resources/bvt/config/config-2.properties @@ -1,4 +1,4 @@ url=jdbc:mock:config-2 testOnBorrow=false maxActive=12 -password=TFxB6eJcgxE1hxOgiwOC/L7zWR/9vnSIfpggI2PTfcvvRhSnCGCPwI9n03fiJiLmRdnDU2/KaVTJYwz8zzkBqg== \ No newline at end of file +password=ns2B+nJLNaoXgGakWqqsP6tWu8ZN25D1FncyKCTB/hNup8LW0g/66iGyrkDBHf9tgPJ8QtLz+upQSyin2g4flg== \ No newline at end of file