使用DES对数据库密码进行加密

在Spring项目中经常需要在jdbc.properties文件中写入数据库连接的用户名和密码,这样在连接传输中是不安全的,我们可以利用对称加密的方法对敏感数据进行加密,在使用的时候再进行解密。比如数据加密算法(Data Encryption Algorithm,DEA),是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码)

实现加密

我们创建一个DESUtil类用于实现加密解密等相关操作。

1、生成密钥

首先定义一个静态方法用于实现密钥对象key的生成。我们首先自定义一个随机数种子KEY_STR用于生成随机数,接着创建随机数生成器secureRandom 并设置种子(相同的种子生成的随机数是一样的)。最后创建密钥生成器并用随机数对象初始化,用密钥生成器创建密钥对象。

package com.tory.shop.util;

import java.security.Key;
import java.security.SecureRandom;

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

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DESUtil {
    private static final Key key;
    private static final String KEY_STR = "ShopKey";    //密钥随机数种子
    private static final String CHARSET = "UTF-8";    //编码方式
    private static final String ALGORITHM = "DES";    //加密算法

    static {
        try {
            //创建基于SHA1的安全随机数生成器
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            //设置随机数种子
            secureRandom.setSeed(KEY_STR.getBytes());
            //创建密钥生成器
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            //使用随机数初始化密钥生成器
            generator.init(secureRandom);
            //生成密钥对象
            key = generator.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

2、字符串加密

加密过程就是首先根据密钥创建加密对象cipher,然后利用base64encoder 将字符串str先转为字节序列,用cipher进行加密后再重新编码为字符串

    //加密字符串
    public static String getEncryptString(String str) {
        BASE64Encoder base64encoder = new BASE64Encoder();
        try {
            //创建加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //根据密钥初始化加密对象
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //将字符串转化为字节序列
            byte[] bytes = str.getBytes(CHARSET);
            //对字节序列进行加密
            byte[] encrypt_bytes = cipher.doFinal(bytes);
            //将字节序列编码为字符串并返回
            return base64encoder.encode(encrypt_bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

3、字符串解密

解密过程和加密类似,先将字符串编码为字节序列,通过cipher解密后再编码为字符串返回

    public static String getDecryptString(String str) {
        BASE64Decoder base64decoder = new BASE64Decoder();
        try {
            byte[] bytes = base64decoder.decodeBuffer(str);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decrypt_bytes = cipher.doFinal(bytes);
            return new String(decrypt_bytes, CHARSET);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

运行加密方法得到加密后的用户名和密码,填写到jdbc.properties文件中

    public static void main(String[] args) {
        System.out.println(getEncryptString("root"));
        System.out.println(getEncryptString("root1234"));
    }

配置spring

原来的配置文件spring-dao.xml如下,通过property-placeholder读取jbdc.properties文件并将读取到的数据库设置以${}方式注入到c3p0连接池bean


    <context:property-placeholder location="classpath:jdbc.properties"/>

    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    ......

现在使用自定义的beanEncryptPropertyPlaceholderConfigure读取数据库变量并对其中加密的属性进行解密

	
    <bean class="com.tory.shop.util.EncryptPropertyPlaceholderConfigure">
        <property name="location" value="classpath:jdbc.properties"/>
    bean>

EncryptPropertyPlaceholderConfigure实现如下,它继承自PropertyPlaceholderConfigurer 类并重写其convertProperty()方法。对传入的propertyName,判断其是否在需要解密的数组encrypt_properties 中,若在则将propertyValue解密后返回,否则直接返回。

package com.tory.shop.util;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import java.util.Arrays;
import java.util.List;

public class EncryptPropertyPlaceholderConfigure extends PropertyPlaceholderConfigurer {
    //要解密的属性
    private List<String> encrypt_properties = Arrays.asList("jdbc.username", "jdbc.password");

    @Override
    protected String convertProperty(String propertyName, String propertyValue) {
        if (encrypt_properties.contains(propertyName)) {
            return DESUtil.getDecryptString(propertyValue);
        } else {
            return propertyValue;
        }
    }
}

你可能感兴趣的:(#,Java,Web商城开发)