一、加密连接数据库明文密码
步骤:
1、对jdbc.property文件的用户名和密码进行加密,我们就需要创建一个加密工具类里面包含加密和解密方法。
2、加密好之后再把jdbc.property里的信息换成加密后的字符。
3、创建一个继承PropertyPlaceHolderConfigure的类用于在程序启动的时候再加载spring-dao.xml后需要解密回来。
4、在需要用到jdbc.property的spring-dao.xml里去掉之前的<context:property-placeholder location="classpath:jdbc.properties" />,然后再声明解密类的bean,配置属性。
1、
三个属性字符串密钥,字符编码,算法,然后使用一个static,static代码块就是用来初始化值key的,我们没有给key赋值就是通过static里的代码快来赋值的。
/**
* DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法
*
* @author ljs
*
*/
public class DESUtil {
private static Key key;
// 密钥makekey
private static String KEY_STR = "myKey";
// 编码
private static String CHARSETNAME = "UTF-8";
// java自带的des算法
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();
}
}
加密方法,这里出现的问题解决Eclipse中无法直接使用Base64Encoder的问题,传入str之后使用base64encoder把字符串转换为byte数组,然后再使用cipher.doFinal把byte数组变成加密后的byte数组,最后再使用使用base64encode.encode把加密后的byte数组变成String。
/**
* 获取加密后的信息
*
* @param str(账号密码)
* @return
*/
public static String getEncryptString(String str) {
// 基于BASE64编码,接收byte[]并转换String
BASE64Encoder base64encoder = new BASE64Encoder();
try {
// 按UTF8编码
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);
}
}
}
解密方法,为什么参数还是str是因为你加密之后的还是字符串,传入str之后,使用base64Decoder把字符串转换为byte数组,然后再用cipher.doFinal转换为加密前的byte数组,最后再把加密前的byte数组转换为String返回。
/**
* 获取解密之后的信息
*
* @param str
* @return
*/
public static String getDecrytString(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);
}
}
}
2、运行main函数之后再把生成的信息填到jdbc.property中
3、
convertProperty参数是从jdbc.property里获取的,例如:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=WnplV/ietfQ=
然后判断property即jdbc.driver是否是前面属性数组里的元素
public class EncryptPropetryPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
// 需要加密的字段数组
private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };
/**
* 对关键的属性进行转换
*/
@Override
protected String convertProperty(String propertyName, String propertyValue) {
if (isEncryptProp(propertyName)) {
// 对已加密的字段进行解密工作
String decryptValue = DESUtil.getDecrytString(propertyValue);
return decryptValue;
} else {
return propertyName;
}
}
/**
* 该属性是否已经加密
*
* @param propertyName
* @return
*/
private boolean isEncryptProp(String propertyName) {
// 若等于需要加密的filed,则进行加密
for (String encryptpropertyName : encryptPropNames) {
if (encryptpropertyName.equals(propertyName))
return true;
}
return false;
}
}
修改spring-dao.xml
<bean class="com.imooc.o2o.util.EncryptPropetryPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
<property name="fileEncoding" value="UTF-8"/>
</bean>
设置短点调试,查看是否解密
debug启动tomcat,然后访问有关数据库的url,http://localhost:8080/o2o/shopadmin/shoplist,这里出错,原因是spring-dao.xml里写错了。属性locations写少一个s,properties写成property。改过来就好。
可以看到propertyname是jdbc.url,因为这个不是加密,所以下一步就直接return,这里直接按f8,又可以看到回到断点的地方propetyname这次是jdbc.username是需要解密的,f6之后可以看到解密成功。
最后它会把动态运行中赋值给spring-dao.xml里的属性。