From 7a77a70fbe85ae77cdd1221c60d0c339985db413 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 1 Sep 2012 09:11:32 +0800 Subject: [PATCH 1/2] fixed test --- .../com/alibaba/druid/bvt/pool/DruidDataSourceDecryptTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceDecryptTest.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceDecryptTest.java index 4dbd8784fd..fd18785e42 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceDecryptTest.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceDecryptTest.java @@ -19,7 +19,7 @@ public class DruidDataSourceDecryptTest { dataSource.setUsername("xiaoyu"); dataSource.setPassword("OJfUm6WCHi7EuXqE6aEc+Po2xFrAGBeSNy8O2jWhV2FTG8/5kbRRr2rjNKhptlevm/03Y0048P7h88gdUOXAYg=="); dataSource.setFilters("config"); - dataSource.setConnectionProperties("config.decrypt=RSA"); + dataSource.setConnectionProperties("config.decrypt=true"); try { dataSource.init(); From 864a883c2c3ca57ac63412ee36691bf6dd9d4327 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 1 Sep 2012 11:58:38 +0800 Subject: [PATCH 2/2] refactor ConfigFilter --- .../druid/filter/config/ConfigFilter.java | 46 ++-- .../druid/filter/config/ConfigTools.java | 196 ++++-------------- .../java/com/alibaba/druid/util/IOUtils.java | 10 +- .../bvt/filter/config/ConfigFilterTest2.java | 43 +++- .../bvt/filter/config/ConfigFilterTest3.java | 77 +++++++ .../bvt/filter/config/ConfigFilterTest4.java | 77 +++++++ .../bvt/filter/config/ConfigToolsTest.java | 20 +- .../resources/bvt/config/config-4.properties | 5 + 8 files changed, 289 insertions(+), 185 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest3.java create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest4.java create mode 100644 src/test/resources/bvt/config/config-4.properties 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 d90503f84c..db1449f1dc 100644 --- a/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java +++ b/src/main/java/com/alibaba/druid/filter/config/ConfigFilter.java @@ -30,6 +30,7 @@ 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.JdbcUtils; +import com.alibaba.druid.util.StringUtils; /** *
@@ -90,15 +91,15 @@ import com.alibaba.druid.util.JdbcUtils;
  */
 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_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_FILE               = "config.file";
+    public static final String CONFIG_DECRYPT            = "config.decrypt";
+    public static final String CONFIG_KEY                = "config.decrypt.key";
 
-    public static final String SYS_PROP_CONFIG_FILE = "druid.config.file";
+    public static final String SYS_PROP_CONFIG_FILE      = "druid.config.file";
+    public static final String SYS_PROP_CONFIG_DECRYPT   = "druid.config.decrypt";
+    public static final String SYS_PROP_CONFIG_KEY       = "druid.config.decrypt.key";
 
     public ConfigFilter(){
     }
@@ -138,8 +139,14 @@ public class ConfigFilter extends FilterAdapter {
         boolean decrypt = false;
 
         String decrypterId = connectinProperties.getProperty(CONFIG_DECRYPT);
-        if (configFileProperties != null && (decrypterId == null || decrypterId.length() == 0)) {
-            decrypterId = configFileProperties.getProperty(CONFIG_DECRYPT);
+        if (decrypterId == null || decrypterId.length() == 0) {
+            if (configFileProperties != null) {
+                decrypterId = configFileProperties.getProperty(CONFIG_DECRYPT);
+            }
+        }
+
+        if (decrypterId == null || decrypterId.length() == 0) {
+            decrypterId = System.getProperty(SYS_PROP_CONFIG_DECRYPT);
         }
 
         if ("true".equals(decrypterId)) {
@@ -191,6 +198,7 @@ public class ConfigFilter extends FilterAdapter {
             }
 
             PublicKey publicKey = getPublicKey(dataSource.getConnectProperties(), info);
+
             String passwordPlainText = ConfigTools.decrypt(publicKey, encryptedPassword);
 
             if (info != null) {
@@ -205,27 +213,13 @@ public class ConfigFilter extends FilterAdapter {
 
     public PublicKey getPublicKey(Properties connectinProperties, Properties configFileProperties) {
         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)) {
+        if (StringUtils.isEmpty(key) && connectinProperties != null) {
             key = connectinProperties.getProperty(CONFIG_KEY);
         }
 
-        if (connectinProperties != null && (publicKeyFile == null || publicKeyFile.length() == 0)) {
-            publicKeyFile = connectinProperties.getProperty(CONFIG_KEY_FILE);
-        }
-
-        if (connectinProperties != null && (x509File == null || x509File.length() == 0)) {
-            x509File = connectinProperties.getProperty(CONFIG_X509_FILE);
-        }
-
-        if (publicKeyFile != null) {
-            return ConfigTools.getPublicKeyByPublicKeyFile(publicKeyFile);
-        }
-
-        if (x509File != null) {
-            return ConfigTools.getPublicKeyByX509(x509File);
+        if (StringUtils.isEmpty(key)) {
+            key = System.getProperty(SYS_PROP_CONFIG_KEY);
         }
 
         return ConfigTools.getPublicKey(key);
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 b3858a2d18..daa16a0da8 100644
--- a/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java
+++ b/src/main/java/com/alibaba/druid/filter/config/ConfigTools.java
@@ -1,14 +1,26 @@
+/*
+ * Copyright 1999-2011 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.alibaba.druid.filter.config;
 
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.security.Key;
 import java.security.KeyFactory;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.SecureRandom;
@@ -27,44 +39,21 @@ public class ConfigTools {
     private static final String DEFAULT_PRIVATE_KEY_STRING = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAocbCrurZGbC5GArEHKlAfDSZi7gFBnd4yxOt0rwTqKBFzGyhtQLu5PRKjEiOXVa95aeIIBJ6OhC2f8FjqFUpawIDAQABAkAPejKaBYHrwUqUEEOe8lpnB6lBAsQIUFnQI/vXU4MV+MhIzW0BLVZCiarIQqUXeOhThVWXKFt8GxCykrrUsQ6BAiEA4vMVxEHBovz1di3aozzFvSMdsjTcYRRo82hS5Ru2/OECIQC2fAPoXixVTVY7bNMeuxCP4954ZkXp7fEPDINCjcQDywIgcc8XLkkPcs3Jxk7uYofaXaPbg39wuJpEmzPIxi3k0OECIGubmdpOnin3HuCP/bbjbJLNNoUdGiEmFL5hDI4UdwAdAiEAtcAwbm08bKN7pwwvyqaCBC//VnEWaq39DCzxr+Z2EIk=";
     public static final String  DEFAULT_PUBLIC_KEY_STRING  = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKHGwq7q2RmwuRgKxBypQHw0mYu4BQZ3eMsTrdK8E6igRcxsobUC7uT0SoxIjl1WveWniCASejoQtn/BY6hVKWsCAwEAAQ==";
 
-    public static void main(String[] args) {
-        System.out.println("**************************************");
-        System.out.println("*                                    *");
-        System.out.println("*           Druid 加密工具           *");
-        System.out.println("*                                    *");
-        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();
-
-        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 void main(String[] args) throws Exception {
+        String password = args[0];
+        System.out.println(encrypt(password));
     }
-    
+
     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);
@@ -83,7 +72,7 @@ public class ConfigTools {
             JdbcUtils.close(in);
         }
     }
-    
+
     public static PublicKey getPublicKey(String publicKeyText) {
         if (publicKeyText == null || publicKeyText.length() == 0) {
             publicKeyText = ConfigTools.DEFAULT_PUBLIC_KEY_STRING;
@@ -99,7 +88,7 @@ public class ConfigTools {
             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);
@@ -125,11 +114,11 @@ public class ConfigTools {
             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;
         }
@@ -140,58 +129,19 @@ public class ConfigTools {
         return new String(plainBytes);
     }
 
-    private static void encrypt() {
-        System.out.println("注意: 如果输入的不是该工具生成的私钥, 请转成PKCS#8格式, 使用下面命令");
-        System.out.println("openssl pkcs8 -topk8 -inform PEM -outform DER -in 原来的Key -nocrypt > 输出文件");
-        String filePath = System.console().readLine("[RSA]请输入私钥文件路径[如果直接回车将使用默认私钥]: ");
-
-        byte[] key = null;
-        if (filePath == null || filePath.length() == 0) {
-            key = Base64.base64ToByteArray(DEFAULT_PRIVATE_KEY_STRING);
-        } else {
-            try {
-                key = getPrivateKeyFromFile(filePath);
-            } catch (Exception e) {
-                System.err.println("读取文件出错. " + e.getMessage());
-                return;
-            }
-        }
-
-        String plainString = System.console().readLine("[RSA]请输入要需要加密的明文: ");
-
-        try {
-            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
-            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(plainString.getBytes());
-            String encryptedString = Base64.byteArrayToBase64(encryptedBytes);
-
-            System.out.println("请记住以下的密文, 长度为[" + encryptedString.length() + "].");
-            System.out.println();
-            System.out.println(encryptedString);
-            System.out.println();
-        } catch (Exception e) {
-            System.err.println("加密错误. ");
-            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");
@@ -201,85 +151,31 @@ public class ConfigTools {
 
         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()) {
-            System.err.println("文件不存在[" + filePath + "]");
-        }
+    public static byte[][] genKeyPairBytes(int keySize) throws NoSuchAlgorithmException {
+        byte[][] keyPairBytes = new byte[2][];
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        FileInputStream in = null;
-        try {
-            in = new FileInputStream(filePath);
-            byte[] b = new byte[512 / 8];
-            int len = 0;
-            while ((len = in.read(b)) != -1) {
-                out.write(b, 0, len);
-            }
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                }
-            }
-        }
+        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
+        gen.initialize(keySize, new SecureRandom());
+        KeyPair pair = gen.generateKeyPair();
 
-        return out.toByteArray();
+        keyPairBytes[0] = pair.getPrivate().getEncoded();
+        keyPairBytes[1] = pair.getPublic().getEncoded();
+
+        return keyPairBytes;
     }
 
-    private static void generateKeys() {
-        System.out.println();
-        System.out.println("[RSA]请选择密钥长度: \n1. 512 \n2. 1024 \n3. 2048");
-        String keySizeString = System.console().readLine("[RSA]请输入选项: ");
+    public static String[] genKeyPair(int keySize) throws NoSuchAlgorithmException {
+        byte[][] keyPairBytes = genKeyPairBytes(keySize);
+        String[] keyPairs = new String[2];
 
-        int keySize = 512;
-        if ("1".equals(keySizeString) || "2".equals(keySizeString) || "3".equals(keySizeString)) {
-            int power = (Integer.valueOf(keySizeString) - 1);
-            keySize = keySize << power;
-        } else {
-            System.err.println("不是一个合法的输入.");
-            return;
-        }
+        keyPairs[0] = Base64.byteArrayToBase64(keyPairBytes[0]);
+        keyPairs[1] = Base64.byteArrayToBase64(keyPairBytes[1]);
 
-        String input = System.console().readLine("[RSA]请输入输出路径: ");
-        if (input == null) {
-            input = "";
-        }
-
-        try {
-            KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
-            gen.initialize(keySize, new SecureRandom());
-            KeyPair pair = gen.generateKeyPair();
-
-            String privateKeyPath = input + ".private.key";
-            saveKey(pair.getPrivate(), privateKeyPath);
-
-            String publicKeyPath = input + ".public.key";
-            saveKey(pair.getPublic(), publicKeyPath);
-
-            System.out.println("Private Key: " + privateKeyPath);
-            System.out.println("public  Key: " + publicKeyPath);
-            System.out.println();
-        } catch (Exception e) {
-            System.err.println("[RSA]创建 RSA 密钥出错. " + e.getMessage());
-        }
-
-    }
-
-    private static void saveKey(Key key, String path) throws Exception {
-        FileOutputStream out = null;
-        try {
-            out = new FileOutputStream(path);
-            out.write(key.getEncoded());
-        } finally {
-            if (out != null) {
-                out.close();
-            }
-        }
+        return keyPairs;
     }
 
 }
diff --git a/src/main/java/com/alibaba/druid/util/IOUtils.java b/src/main/java/com/alibaba/druid/util/IOUtils.java
index eb5cba6956..8f82a47141 100644
--- a/src/main/java/com/alibaba/druid/util/IOUtils.java
+++ b/src/main/java/com/alibaba/druid/util/IOUtils.java
@@ -63,14 +63,18 @@ public class IOUtils {
                 return null;
             }
             
-            ByteArrayOutputStream output = new ByteArrayOutputStream();
-            copy(in, output);
-            return output.toByteArray();
+            return readByteArray(in);
         } finally {
             JdbcUtils.close(in);
         }
     }
     
+    public static byte[] readByteArray(InputStream input) throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        copy(input, output);
+        return output.toByteArray();
+    }
+    
     public static long copy(InputStream input, OutputStream output)
             throws IOException {
         final int EOF = -1;
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest2.java b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest2.java
index 36ffa94206..083e785eaf 100644
--- a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest2.java
+++ b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest2.java
@@ -23,7 +23,7 @@ public class ConfigFilterTest2 extends TestCase {
     public void test_decrypt() throws Exception {
         dataSource.addConnectionProperty(ConfigFilter.CONFIG_FILE, "bvt/config/config-0.properties");
         Assert.assertEquals(1, dataSource.getProxyFilters().size());
-        
+
         dataSource.init();
 
         Assert.assertEquals("jdbc:mock:config-0", dataSource.getUrl());
@@ -42,7 +42,7 @@ public class ConfigFilterTest2 extends TestCase {
         Assert.assertEquals(11, dataSource.getMaxActive());
         Assert.assertEquals(3, dataSource.getProxyFilters().size());
     }
-    
+
     public void test_decrypt2() throws Exception {
         dataSource.addConnectionProperty(ConfigFilter.CONFIG_FILE, "bvt/config/config-2.properties");
         dataSource.addConnectionProperty(ConfigFilter.CONFIG_DECRYPT, "true");
@@ -55,16 +55,49 @@ public class ConfigFilterTest2 extends TestCase {
         Assert.assertEquals(12, dataSource.getMaxActive());
         Assert.assertEquals("abcdefg1234567890", dataSource.getPassword());
     }
-    
+
     public void test_decrypt3() throws Exception {
         dataSource.addConnectionProperty(ConfigFilter.CONFIG_FILE, "bvt/config/config-3.properties");
         Assert.assertEquals(1, dataSource.getProxyFilters().size());
-        
+
         dataSource.init();
-        
+
         Assert.assertEquals("jdbc:mock:config-3", dataSource.getUrl());
         Assert.assertEquals(false, dataSource.isTestOnBorrow());
         Assert.assertEquals(13, dataSource.getMaxActive());
         Assert.assertEquals("abcdefg1234567890", dataSource.getPassword());
     }
+
+    public void test_decrypt4() throws Exception {
+        String file = Thread.currentThread().getContextClassLoader().getResource("bvt/config/config-3.properties").getFile();
+        dataSource.addConnectionProperty(ConfigFilter.CONFIG_FILE, "file://" + file);
+        Assert.assertEquals(1, dataSource.getProxyFilters().size());
+
+        dataSource.init();
+
+        Assert.assertEquals("jdbc:mock:config-3", dataSource.getUrl());
+        Assert.assertEquals(false, dataSource.isTestOnBorrow());
+        Assert.assertEquals(13, dataSource.getMaxActive());
+        Assert.assertEquals("abcdefg1234567890", dataSource.getPassword());
+    }
+
+    public void test_decrypt5() throws Exception {
+        Assert.assertEquals(1, dataSource.getProxyFilters().size());
+
+        try {
+            String file = Thread.currentThread().getContextClassLoader().getResource("bvt/config/config-2.properties").getFile();
+            System.setProperty(ConfigFilter.SYS_PROP_CONFIG_FILE, "file://" + file);
+            System.setProperty(ConfigFilter.SYS_PROP_CONFIG_DECRYPT, "true");
+
+            dataSource.init();
+
+            Assert.assertEquals("jdbc:mock:config-2", dataSource.getUrl());
+            Assert.assertEquals(false, dataSource.isTestOnBorrow());
+            Assert.assertEquals(12, dataSource.getMaxActive());
+            Assert.assertEquals("abcdefg1234567890", dataSource.getPassword());
+        } finally {
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_FILE);
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_DECRYPT);
+        }
+    }
 }
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest3.java b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest3.java
new file mode 100644
index 0000000000..ec7d3f18ae
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest3.java
@@ -0,0 +1,77 @@
+package com.alibaba.druid.bvt.filter.config;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Properties;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.alibaba.druid.filter.config.ConfigFilter;
+import com.alibaba.druid.filter.config.ConfigTools;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import com.alibaba.druid.util.JdbcUtils;
+
+public class ConfigFilterTest3 extends TestCase {
+
+    private DruidDataSource dataSource;
+
+    protected void setUp() throws Exception {
+        dataSource = new DruidDataSource();
+        dataSource.setFilters("config");
+    }
+
+    protected void tearDown() throws Exception {
+        JdbcUtils.close(dataSource);
+    }
+
+    public void test_0() throws Exception {
+        String password = "abcdefg1234";
+        String[] keys = ConfigTools.genKeyPair(1024);
+
+        File file = File.createTempFile("MyTest", Long.toString(System.nanoTime()));
+        Properties properties = new Properties();
+        properties.put(DruidDataSourceFactory.PROP_URL, "jdbc:mock:xx0");
+        properties.put(DruidDataSourceFactory.PROP_USERNAME, "sa");
+        properties.put(DruidDataSourceFactory.PROP_PASSWORD, ConfigTools.encrypt(keys[0], password));
+        properties.put(ConfigFilter.CONFIG_DECRYPT, "true");
+        properties.store(new FileOutputStream(file), "");
+
+        dataSource.getConnectProperties().put(ConfigFilter.CONFIG_KEY, keys[1]);
+        dataSource.getConnectProperties().put(ConfigFilter.CONFIG_FILE, "file://" + file.getAbsolutePath());
+
+        dataSource.init();
+
+        Assert.assertEquals("jdbc:mock:xx0", dataSource.getUrl());
+        Assert.assertEquals("sa", dataSource.getUsername());
+        Assert.assertEquals(password, dataSource.getPassword());
+    }
+
+    public void test_sys_property() throws Exception {
+        String password = "abcdefg1234";
+        String[] keys = ConfigTools.genKeyPair(1024);
+
+        File file = File.createTempFile("MyTest", Long.toString(System.nanoTime()));
+        Properties properties = new Properties();
+        properties.put(DruidDataSourceFactory.PROP_URL, "jdbc:mock:xx0");
+        properties.put(DruidDataSourceFactory.PROP_USERNAME, "sa");
+        properties.put(DruidDataSourceFactory.PROP_PASSWORD, ConfigTools.encrypt(keys[0], password));
+        properties.put(ConfigFilter.CONFIG_DECRYPT, "true");
+        properties.store(new FileOutputStream(file), "");
+
+        System.getProperties().put(ConfigFilter.SYS_PROP_CONFIG_KEY, keys[1]);
+        System.getProperties().put(ConfigFilter.SYS_PROP_CONFIG_FILE, "file://" + file.getAbsolutePath());
+
+        try {
+            dataSource.init();
+
+            Assert.assertEquals("jdbc:mock:xx0", dataSource.getUrl());
+            Assert.assertEquals("sa", dataSource.getUsername());
+            Assert.assertEquals(password, dataSource.getPassword());
+        } finally {
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_KEY);
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_FILE);
+        }
+    }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest4.java b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest4.java
new file mode 100644
index 0000000000..4e64ab74d8
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigFilterTest4.java
@@ -0,0 +1,77 @@
+package com.alibaba.druid.bvt.filter.config;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Properties;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.alibaba.druid.filter.config.ConfigFilter;
+import com.alibaba.druid.filter.config.ConfigTools;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+import com.alibaba.druid.util.JdbcUtils;
+
+public class ConfigFilterTest4 extends TestCase {
+
+    private DruidDataSource dataSource;
+
+    protected void setUp() throws Exception {
+        dataSource = new DruidDataSource();
+        dataSource.setFilters("config");
+    }
+
+    protected void tearDown() throws Exception {
+        JdbcUtils.close(dataSource);
+    }
+
+    public void test_0() throws Exception {
+        String password = "abcdefg1234";
+        String[] keys = ConfigTools.genKeyPair(1024);
+
+        File file = File.createTempFile("MyTest", Long.toString(System.nanoTime()));
+        Properties properties = new Properties();
+        properties.put(DruidDataSourceFactory.PROP_URL, "jdbc:mock:xx0");
+        properties.put(DruidDataSourceFactory.PROP_USERNAME, "sa");
+        properties.put(DruidDataSourceFactory.PROP_PASSWORD, ConfigTools.encrypt(keys[0], password));
+        properties.put(ConfigFilter.CONFIG_DECRYPT, "true");
+        properties.store(new FileOutputStream(file), "");
+
+        dataSource.getConnectProperties().put(ConfigFilter.CONFIG_KEY, keys[1]);
+        dataSource.getConnectProperties().put(ConfigFilter.CONFIG_FILE, "file://" + file.getAbsolutePath());
+
+        dataSource.init();
+
+        Assert.assertEquals("jdbc:mock:xx0", dataSource.getUrl());
+        Assert.assertEquals("sa", dataSource.getUsername());
+        Assert.assertEquals(password, dataSource.getPassword());
+    }
+
+    public void test_sys_property() throws Exception {
+        String password = "abcdefg1234";
+        String[] keys = ConfigTools.genKeyPair(1024);
+
+        File file = File.createTempFile("MyTest", Long.toString(System.nanoTime()));
+        Properties properties = new Properties();
+        properties.put(DruidDataSourceFactory.PROP_URL, "jdbc:mock:xx0");
+        properties.put(DruidDataSourceFactory.PROP_USERNAME, "sa");
+        properties.put(DruidDataSourceFactory.PROP_PASSWORD, ConfigTools.encrypt(keys[0], password));
+        properties.put(ConfigFilter.CONFIG_DECRYPT, "true");
+        properties.store(new FileOutputStream(file), "");
+
+        System.getProperties().put(ConfigFilter.SYS_PROP_CONFIG_KEY, keys[1]);
+        System.getProperties().put(ConfigFilter.SYS_PROP_CONFIG_FILE, "file://" + file.getAbsolutePath());
+
+        try {
+            dataSource.init();
+
+            Assert.assertEquals("jdbc:mock:xx0", dataSource.getUrl());
+            Assert.assertEquals("sa", dataSource.getUsername());
+            Assert.assertEquals(password, dataSource.getPassword());
+        } finally {
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_KEY);
+            System.clearProperty(ConfigFilter.SYS_PROP_CONFIG_FILE);
+        }
+    }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigToolsTest.java b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigToolsTest.java
index bb5772b6ae..d981689e1a 100644
--- a/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigToolsTest.java
+++ b/src/test/java/com/alibaba/druid/bvt/filter/config/ConfigToolsTest.java
@@ -1,5 +1,7 @@
 package com.alibaba.druid.bvt.filter.config;
 
+import java.util.Random;
+
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
@@ -11,7 +13,23 @@ public class ConfigToolsTest extends TestCase {
         String plainText = "abcdef";
         String cipherText = ConfigTools.encrypt(plainText);
         String decipherText = ConfigTools.decrypt(cipherText);
-        
+
         Assert.assertEquals(plainText, decipherText);
     }
+
+    public void test_genKeys() throws Exception {
+        String plainText = Long.toString(new Random().nextLong());
+        String[] keys = ConfigTools.genKeyPair(512);
+
+        String cipherText = ConfigTools.encrypt(keys[0], plainText);
+        Assert.assertEquals(plainText, ConfigTools.decrypt(keys[1], cipherText));
+    }
+    
+    public void test_genKeys1024() throws Exception {
+        String plainText = Long.toString(new Random().nextLong());
+        String[] keys = ConfigTools.genKeyPair(1024);
+        
+        String cipherText = ConfigTools.encrypt(keys[0], plainText);
+        Assert.assertEquals(plainText, ConfigTools.decrypt(keys[1], cipherText));
+    }
 }
diff --git a/src/test/resources/bvt/config/config-4.properties b/src/test/resources/bvt/config/config-4.properties
new file mode 100644
index 0000000000..47186f99d1
--- /dev/null
+++ b/src/test/resources/bvt/config/config-4.properties
@@ -0,0 +1,5 @@
+config.decrypt=true
+url=jdbc:mock:config-4
+testOnBorrow=false
+maxActive=14
+password=ns2B+nJLNaoXgGakWqqsP6tWu8ZN25D1FncyKCTB/hNup8LW0g/66iGyrkDBHf9tgPJ8QtLz+upQSyin2g4flg==
\ No newline at end of file