一.背景
数据库配置以明文方式展示如图,会造成安全隐患,如果有黑客入侵会造成密码泄露,信息窃取和破坏等。
二.加密步骤
1.对数据库信息加密:
对数据库中的账号和密码信息进行加密(选择一种算法)然后替换掉原来的明文数据库配置信息。
2.解密:
在Spring读取使用配置文件时进行解密成明文。
三.编码实现
1.加密类实现:(采用DES算法)
1.1DES算法介绍:
DES是一种对称算法,即加密和解密使用的是相同的算法。
详细介绍:https://blog.csdn.net/qq_27570955/article/details/52442092
1.2实现:
获得加密后的账号密码后替换原先的数据库明文配置。
DESUtils.Java:
1 import java.security.Key; 2 import java.security.SecureRandom; 3 4 import javax.crypto.Cipher; 5 import javax.crypto.KeyGenerator; 6 7 import sun.misc.BASE64Decoder; 8 import sun.misc.BASE64Encoder; 9 10 public class DESUtils { 11 12 private static Key key; 13 // 设置密钥key 14 private static String KEY_STR = "myKey"; 15 private static String CHARSETNAME = "UTF-8"; 16 private static String ALGORITHM = "DES"; 17 18 // 静态代码块 19 static { 20 try { 21 // 生成DES算法对象 22 KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM); 23 // 运用SHA1安全策略 24 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); 25 // 设置上密钥种子 26 secureRandom.setSeed(KEY_STR.getBytes()); 27 // 初始化基于SHA1的算法对象 28 generator.init(secureRandom); 29 // 生成密钥对象 30 key = generator.generateKey(); 31 generator = null; 32 } catch (Exception e) { 33 throw new RuntimeException(e); 34 } 35 } 36 37 /** 38 * 获取加密后的信息 39 * 40 * @param str 41 * @return 42 */ 43 public static String getEncryptString(String str) { 44 // 基于BASE64编码,接收byte[]并转换为String 45 BASE64Encoder base64encoder = new BASE64Encoder(); 46 try { 47 // 按UTF-8编码 48 byte[] bytes = str.getBytes(CHARSETNAME); 49 // 获取加密对象 50 Cipher cipher = Cipher.getInstance(ALGORITHM); 51 // 初始化密码信息 52 cipher.init(Cipher.ENCRYPT_MODE, key); 53 // 加密 54 byte[] doFinal = cipher.doFinal(bytes); 55 // byte[] to encode好的String并返回 56 return base64encoder.encode(doFinal); 57 } catch (Exception e) { 58 // TODO: handle exception 59 throw new RuntimeException(e); 60 } 61 } 62 63 /** 64 * 获取解密后的信息 65 * 66 * @param str 67 * @return 68 */ 69 public static String getDecryptString(String str) { 70 //基于BASE64编码,接收byte[]并转换为String 71 BASE64Decoder base64decoder = new BASE64Decoder(); 72 try { 73 //将字符串decode为byte[] 74 byte[] bytes = base64decoder.decodeBuffer(str); 75 //获取解密对象 76 Cipher cipher = Cipher.getInstance(ALGORITHM); 77 //初始化解密信息 78 cipher.init(Cipher.DECRYPT_MODE, key); 79 //解密 80 byte[] doFinal = cipher.doFinal(bytes); 81 //返回解密之后的信息 82 return new String(doFinal, CHARSETNAME); 83 } catch (Exception e) { 84 // TODO: handle exception 85 throw new RuntimeException(e); 86 } 87 } 88 89 public static void main(String[] args) { 90 System.out.println(getEncryptString("root")); 91 System.out.println(getEncryptString("123654")); 92 93 } 94 95 }
2.配置文件解析类:
EncryptPropertyPlaceholderConfigurer.java:
1 import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; 2 3 public class EncryptPropertyPlaceholderConfigurer extends 4 PropertyPlaceholderConfigurer { 5 //需要加密的字段数组 6 private String[] encryptPropNames = { "jdbc.username", "jdbc.password" }; 7 /** 8 * 对关键的属性进行转换 9 */ 10 @Override 11 protected String convertProperty(String propertyName, String propertyValue) { 12 if (isEncryptProp(propertyName)) { 13 //对已加密的字段进行阶段工作 14 String decryptValue = DESUtils.getDecryptString(propertyValue); 15 return decryptValue; 16 } else { 17 return propertyValue; 18 } 19 } 20 /** 21 * 该属性是否已经加密 22 * @param propertyName 23 * @return 24 */ 25 private boolean isEncryptProp(String propertyName) { 26 //若等于需要加密的field,则进行加密 27 for (String encryptpropertyName : encryptPropNames) { 28 if (encryptpropertyName.equals(propertyName)) 29 return true; 30 } 31 return false; 32 } 33 }
未修改前默认使用:
<context:property-placeholder location="classpath:jdbc.properties" />
配置为自己写的:通过文件解析类将密文解析为明文赋值给对应字段。
<bean class="com.swpu.o2o.util.EncryptPropertyPlaceholderConfigurer"> <property name="locations"> <list> <!-- 需要解密的文件 --> <value>classpath:jdbc.properties</value> </list> </property> <!-- 设置编码为UTF-8 --> <property name="fileEncoding" value="UTF-8"></property> </bean>