springMVC web项目 对访问数据库的用户名密码进行加密解密
在使用springMVC开发web项目中,数据库的用户名,密码一般都是配置在.properties文件中
然后在通过.xml配置文件引入.properties的变量,例如
在config.properties文件中,配置如下变量,变量值配置在pom.xml的profile标签下,在此就不再赘述
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc\:mysql\://${p.jdbc.url}/${p.jdbc.dbname}?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull&rewriteBatchedStatements\=true jdbc.username=${p.jdbc.username} jdbc.password=${p.jdbc.password}
在applicationContext.xml中,通过如下标签引入这些变量值
<!-- 将多个配置文件读取到容器中,交给Spring管理 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean>
这样对于是明文的帐号,密码,是没有问题的。但是如果我在配置文件中的帐号密码是加密后的,那么如何进行使用配置呢?
解决办法:
1.首先确定加密解密算法,这种情况下,我们肯定选择是对称性加密解密算法,首选DES算法,在这里就拿他举例
2.完成加密解密算法,这个代码很简单,就不赘述,密钥自己决定,保密即可
public class DESUtils { private static Key key; private static String KEY_STR="mykey"; static{ try { KeyGenerator generator = KeyGenerator.getInstance("DES"); SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(KEY_STR.getBytes()); generator.init(secureRandom); key = generator.generateKey(); generator=null; } catch (Exception e) { throw new RuntimeException(e); } } /** * 对字符串进行加密,返回BASE64的加密字符串 * <功能详细描述> * @param str * @return * @see [类、类#方法、类#成员] */ public static String getEncryptString(String str){ BASE64Encoder base64Encoder = new BASE64Encoder(); System.out.println(key); try { byte[] strBytes = str.getBytes("UTF-8"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] encryptStrBytes = cipher.doFinal(strBytes); return base64Encoder.encode(encryptStrBytes); } catch (Exception e) { throw new RuntimeException(e); } } /** * 对BASE64加密字符串进行解密 * <功能详细描述> * @param str * @return * @see [类、类#方法、类#成员] */ public static String getDecryptString(String str){ BASE64Decoder base64Decoder = new BASE64Decoder(); try { byte[] strBytes = base64Decoder.decodeBuffer(str); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptStrBytes = cipher.doFinal(strBytes); return new String(encryptStrBytes,"UTF-8"); } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) { String name ="root"; String password="1234"; String encryname = getEncryptString(name); String encrypassword = getEncryptString(password); System.out.println(encryname); System.out.println(encrypassword); System.out.println(getDecryptString(encryname)); System.out.println(getDecryptString(encrypassword)); } }
3.springMVC中需要实现解密的接口
需要覆盖convertProperty方法,encryptPropNames存储的是需要解密的属性
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 = DESUtils.getDecryptString(propertyValue); System.out.println(decryptValue); return decryptValue; }else { return propertyValue; } } private boolean isEncryptProp(String propertyName) { for (String encryptName : encryptPropNames) { if (encryptName.equals(propertyName)) { return true; } } return false; } }
4.配置这个解密类
用 <bean id="propertyConfigurer" class="org.utils.EncryptPropertyPlaceholderConfigurer" > <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean> 替换 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:/properties/*.properties</value> </list> </property> </bean>
备注:实际使用中可能会遇到 sun.misc.BASE64Encoder无法使用的问题,下面给出解决办法
解决方案1(推荐):
只需要在project build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
解决方案2:
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Deprecated and trstricted API -> Forbidden reference (access rules): -> change to warning