Spring 管理下的web项目,对Properties文件重要参数的加密解密处理

javaWeb项目中往往我们会把jdbc/redis等的属性配置放在properties文件中,但是又不想让非开发人员看到某些重要配置信息,所以需要对这样类似与用户名、密码等的字段进行加密,但是Spring管理项目启动时候只去读取,所以必须继承PropertyPlaceholderConfigurer 类来实现读取前的解密过程

加密类

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

public class DesEncryptUtil
{
    public static void main(String[] args) throws Exception
    {
        /** 生成KEY */
        // createKey("../key");

        Key key = getKey("../key");

        /** 加密 */
        byte[] result = doEncrypt(key, "");
//      System.out.println(result);
//      System.out.println(result.length);
        String buf = "";
        for (int i = 0; i < result.length; i++)
        {
            buf += result[i] + ",";
        }
        System.out.println(buf);

        /** 解密 */
//      System.out.println(doDecrypt(key, buf));
    }

    @SuppressWarnings("restriction")
    public static void createKey(String keyFilePath) throws Exception
    {
        Security.insertProviderAt(new com.sun.crypto.provider.SunJCE(), 1);
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(keyFilePath));
        oos.writeObject(key);
        oos.close();
    }

    @SuppressWarnings("resource")
    public static Key getKey(String keyFilePath)
    {
        try
        {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(keyFilePath));
            return (Key) ois.readObject();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    // 对字符串进行加密
    public static byte[] doEncrypt(Key key, String str)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] raw = cipher.doFinal(str.getBytes());
            return raw;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    // 对字符串进行解密
    public static String doDecrypt(Key key, String buf)
    {
        try
        {
            String[] strArray = buf.split(",");
            byte[] resultStr = new byte[strArray.length];
            for (int i = 0; i < strArray.length; i++)
            {
                resultStr[i] = new Byte(strArray[i]) ;
            }

            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] raw = cipher.doFinal(resultStr);
            return new String(raw);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

之所以该类加密的不是文件而是字符串,是有部分原因的: 
1- 一般数据库等重要配置信息不是单独放在一个properties文件中的,其下面还是会有其他配置参数的,但是那些参数我们并不想去加密,甚至回经常去修改。 
2- 如果加密的是整个properties文件,当修改其他参数麻烦,系统启动错误或者其他配置的bug,也不好去查找。 
如果需要去对整个文件加密,可以去看一下 http://blog.csdn.net/yaerfeng/article/details/26561791 中的加密方法。

PropertiesConstant常量类

public class PropertiesConstant
{

    public static final String REDIS_HOST = "redis.host";

    public static final String REDIS_PORT = "redis.port";

    public static final String REDIS_PASS = "redis.pass";

    public static final String JDBC_URL = "jdbc_url";

    public static final String JDBC_USERNAME = "jdbc_username";

    public static final String JDBC_PASSWORD = "jdbc_password";

}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

DecryptPropertyPlaceholderConfigurer 类

import java.security.Key;
import java.util.Properties;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import com.rrcp.mgmt.util.DesEncryptUtil;
import com.rrcp.mgmt.util.PropertiesConstant;

public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer
{
    private final String rootPath = getClass().getResource("/").getFile().toString();

    protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException
    {
        Key key = DesEncryptUtil.getKey(rootPath + "../key");  //具体路径得根据自己生成的key文件路径

        try
        {
            String redis_host = props.getProperty(PropertiesConstant.REDIS_HOST);
            if(redis_host != null)
            {
                props.setProperty(PropertiesConstant.REDIS_HOST, DesEncryptUtil.doDecrypt(key, redis_host));
            }

            String redis_port = props.getProperty(PropertiesConstant.REDIS_PORT);
            if(redis_port != null)
            {
                props.setProperty(PropertiesConstant.REDIS_PORT, DesEncryptUtil.doDecrypt(key, redis_port));
            }

            String redis_pass = props.getProperty(PropertiesConstant.REDIS_PASS);
            if(redis_pass != null)
            {
                props.setProperty(PropertiesConstant.REDIS_PASS, DesEncryptUtil.doDecrypt(key, redis_pass));
            }

            String jdbc_url = props.getProperty(PropertiesConstant.JDBC_URL);
            if(jdbc_url != null)
            {
                props.setProperty(PropertiesConstant.JDBC_URL, DesEncryptUtil.doDecrypt(key, jdbc_url));
            }

            String jdbc_username = props.getProperty(PropertiesConstant.JDBC_USERNAME);
            if(jdbc_username != null)
            {
                props.setProperty(PropertiesConstant.JDBC_USERNAME, DesEncryptUtil.doDecrypt(key, jdbc_username));
            }

            String jdbc_password = props.getProperty(PropertiesConstant.JDBC_PASSWORD);
            if(jdbc_password != null)
            {
                props.setProperty(PropertiesConstant.JDBC_PASSWORD, DesEncryptUtil.doDecrypt(key, jdbc_password));
            }

            super.processProperties(beanFactory, props);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw new BeanInitializationException(e.getMessage());
        }
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

SpringConfig.xml中的配置(关键)

这里写图片描述

注意:如果使用自定义的类来加载properties文件,需要配置<bean id="propertyConfigurer"....></bean>并且红色框1处不能存在,因为原本是通过上面的配置加载文件的,现在添加了下面的方式两种方式就不能并存了(建议将红框中的配置文件全放在下面的value中),否则会启动失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值