前言
我们常常在写数据库配置文件jdbc.properties的时候,都是以明文方式来显示,这样做其实是很不安全的,万一被黑客爬取到这些信息连接上数据库,造成数据泄露是很危险的。所以,我们想到对明文进行加密,使用密文来显示是个不错的方法~
加密一般分为可逆加密和不可逆加密,其中可逆加密一般又分为对称加密和非对称加密,对称加密是使用了同样的密钥进行加密解密,而非对称加密则是使用公钥加密之后必须使用私钥来解密。不可逆加密之后是无法解密的。DES加密就是一种对称加密。
现阶段先不研究加密算法,主要看看在Java中如何使用DES进行加密和解密的~
一、创建DESUtil工具类
package com.yaya.o2o.util.jdbcpwddes;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
import java.security.SecureRandom;
// 对称加密算法
public class DESUtil {
private static Key key;
// 设置密钥key
private static String KEY_STR = "myKey";
private static String CHARSETNAME = "UTF-8";
private static String ALGORITHM = "DES";
static {
try {
// 生成DES算法对象
KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
// 运行SHA1安全策略
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
// 设置上密钥种子
secureRandom.setSeed(KEY_STR.getBytes());
// 初始化基于SHA1的算法对象
generator.init(secureRandom);
// 生成密钥对象
key = generator.generateKey();
generator = null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 获取加密后的信息
public static String getEncryptString(String str) {
// 基于BASE64编码,接收byte[]并转换为String
BASE64Encoder base64encoder = new BASE64Encoder();
try {
// 按UTF-8编码
byte[] bytes = str.getBytes(CHARSETNAME);
// 获取加密对象
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化密码信息
cipher.init(Cipher.ENCRYPT_MODE, key);
// 加密
byte[] doFinal = cipher.doFinal(bytes);
// byte[] to encode好的String并返回
return base64encoder.encode(doFinal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 获取解密之后的信息
public static String getDecryptString(String str) {
// 基于BASE64编码,接收byte[]并转换为String
BASE64Decoder base64decoder = new BASE64Decoder();
try {
// 将字符串decode成byte[]
byte[] bytes = base64decoder.decodeBuffer(str);
// 获取解密对象
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化解密信息
cipher.init(Cipher.DECRYPT_MODE, key);
// 解密
byte[] doFinal = cipher.doFinal(bytes);
// 返回解密之后的信息
return new String(doFinal, CHARSETNAME);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 测试
public static void main(String[] args) {
System.out.println(getEncryptString("testusername"));
System.out.println(getEncryptString("testpassword"));
}
}
然后我们就可以在jdbc.properties配置文件里写入经过加密的用户名和密码~
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://39.105.67.70:3306/o2o?useUnicode=true&characterEncoding=utf8&test?useSSL=false
jdbc.username=o2T4v1gWfIeAFco3uKKnAA==
jdbc.password=9DKv3sidTjyolrOKY3mHZw==
二、创建EncryptPropertyPlaceholderConfigurer类
加密完成了,但是我们需要在tomcat启动之后,加载到sapring-dao.xml的配置的时候,将这些加密信息解密回来,只有解密了,才能通过正确的用户名和密码连接到数据库。所以我们需要EncryptPropertyPlaceholderConfigurer这个类,继承PropertyPlaceholderConfigurer类,建立与配置文件的关联,并且将加密的字段进行解密。
package com.yaya.o2o.util.jdbcpwddes;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
// 需要加密的字段数组
private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };
// 对关键的属性进行转换
@Override
protected String convertProperty(String propertyName, String propertyValue) {
if (isEncryptProp(propertyName)) {
// 解密
String decryptValue = DESUtil.getDecryptString(propertyValue);
return decryptValue;
} else {
return propertyValue;
}
}
// 判断该属性是否加密
private boolean isEncryptProp(String propertyName) {
for (String encryptpropertyName : encryptPropNames) {
if (encryptpropertyName.equals(propertyName))
return true;
}
return false;
}
}
三、修改spring-dao.xml的相关配置
准备工作都做好了,现在只需要修改相关配置就能实现了~
之前我们配置数据库相关参数的属性是这样写的:
<context:property-placeholder location="classpath:jdbc.properties"/>
现在将它删掉,改成如下所示:
<bean class="com.yaya.o2o.util.jdbcpwddes.EncryptPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
<property name="fileEncoding" value="UTF-8"/>
</bean>
这样就能在启动tomcat之后,对加密信息进行解密了~接下来就能顺利连接数据库了!
如果之后还有想要进行解密的文件,加在<value>就可以了。
这样就实现了数据库配置文件密文显示的功能~