spring读取加密属性

在开发和设计过程中,通常需要对一些配置数据进行加密,如数据库的连接方式等,在读取到加密数据后,我们必须解密后才能使用。

以下是来自书籍《Spring 3.x 企业应用开发实战》示例,可做参考!
一、编写加密代码DESUtil.java
/**
* DESUtil.java
* cn.com.songjy
* Function: TODO
*
* version date author
* ──────────────────────────────────
* 1.0 2013-9-25 songjy
*
* Copyright (c) 2013, TNT All Rights Reserved.
*/

package cn.com.songjy;

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

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

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

/**
* ClassName:DESUtil
*
* @author songjy
* @version 1.0
* @since v1.0
* @Date 2013-9-25 下午4:19:48
*/

public class DESUtil {

private static Log log = LogFactory.getLog(DESUtil.class);

public static void main(String[] args) {

if (null != args)
if (1 <= args.length)
for (String src : args)
log.info(src + ":" + encrypt(src));

}

/* 1、指定DES加密解密所用的密钥 */
private static Key key;
private static String KEY_STR = "myKey";

static {
try {
KeyGenerator generator = KeyGenerator.getInstance("DES");
generator.init(new SecureRandom(KEY_STR.getBytes()));
key = generator.generateKey();
generator = null;
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
}
}

/* 2、对字符串进行DES加密,返回BASE64编码的加密字符串 */
public static String encrypt(String src/* 明文 */) {
BASE64Encoder base64en = new BASE64Encoder();
try {
byte[] src_byte = src.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] final_byte = cipher.doFinal(src_byte);
return base64en.encode(final_byte);
} /*
* catch (UnsupportedEncodingException e) { log.info(e.getMessage(), e);
* } catch (NoSuchAlgorithmException e) { log.info(e.getMessage(), e); }
* catch (NoSuchPaddingException e) { log.info(e.getMessage(), e); }
*/catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}

/* 3、对BASE64编码的加密字符串进行解密,返回解密后的字符串 */
public static String decrypt(String src/* 密文 */) {
BASE64Decoder base64de = new BASE64Decoder();
try {
byte[] src_byte = base64de.decodeBuffer(src);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypt_byte = cipher.doFinal(src_byte);
return new String(decrypt_byte, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}


二、继承PropertyPlaceholderConfigurer类并实现接口convertProperty
/**
* EncryptPropertyPlaceholderConfigurer.java
* cn.com.songjy
* Function: TODO
*
* version date author
* ──────────────────────────────────
* 1.0 2013-9-25 songjy
*
* Copyright (c) 2013, TNT All Rights Reserved.
*/

package cn.com.songjy;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

/**
* ClassName:EncryptPropertyPlaceholderConfigurer
*
* @author songjy
* @version 1.0
* @since v1.0
* @Date 2013-9-25 下午4:22:13
*/

public class EncryptPropertyPlaceholderConfigurer extends
PropertyPlaceholderConfigurer {

private Log log = LogFactory.getLog(EncryptPropertyPlaceholderConfigurer.class);

/**
* (non-Javadoc)
* @see org.springframework.beans.factory.config.PropertyResourceConfigurer#convertProperty(java.lang.String, java.lang.String)
*/
@Override
protected String convertProperty(String propertyName, String propertyValue) {

if(encryptPropNames.contains(propertyName))//属性propertyName的值加密了,需要解密
return DESUtil.decrypt(propertyValue);

return super.convertProperty(propertyName, propertyValue);

}

private List<String> encryptPropNames;//保存加密的属性字段

public List<String> getEncryptPropNames() {
return encryptPropNames;
}

public void setEncryptPropNames(List<String> encryptPropNames) {
for (String string : encryptPropNames) {
log.info("属性"+string+"的值已加密");
}
this.encryptPropNames = encryptPropNames;
}
}


三、编写属性文件保存类,测试时用
/**
* MyConfig.java
* cn.com.songjy
* Function: TODO
*
* version date author
* ──────────────────────────────────
* 1.0 2013-9-26 songjy
*
* Copyright (c) 2013, TNT All Rights Reserved.
*/

package cn.com.songjy;

/**
* ClassName:MyConfig
*
* @author songjy
* @version 1.0
* @since v1.0
* @Date 2013-9-26 上午9:31:56
*/

public class MyConfig {

private String username;
private String password;

private String username1;
private String password1;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername1() {
return username1;
}
public void setUsername1(String username1) {
this.username1 = username1;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}

}


四、创建属性文件
song.properties
song1.properties
其中
song.properties保存的是密文,如下:
username=Pa3HE99AWOg=
password=QAHlVoUc49w=

song.properties保存的是明文,如下:
username1=songjy
password1=123456

五、编写Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean class="cn.com.songjy.EncryptPropertyPlaceholderConfigurer">
<property name="encryptPropNames">
<list>
<value>username</value>
<value>password</value>
</list>
</property>
<property name="locations">
<list>
<value>classpath:cn/com/songjy/song.properties</value>
<value>classpath:cn/com/songjy/song1.properties</value>
</list>
</property>
</bean>

<bean id="my" class="cn.com.songjy.MyConfig">
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="username1" value="${username1}"/>
<property name="password1" value="${password1}"/>
</bean>

</beans>

六、测试类编写
/**
* Test.java
* cn.com.songjy
* Function: TODO
*
* version date author
* ──────────────────────────────────
* 1.0 2013-9-26 songjy
*
* Copyright (c) 2013, TNT All Rights Reserved.
*/

package cn.com.songjy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* ClassName:Test
*
* @author songjy
* @version 1.0
* @since v1.0
* @Date 2013-9-26 上午9:35:31
*/

public class Test {

/**
* @method main
* @param args
* @since v1.0
*/

public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext("cn/com/songjy/beans.xml");

//MyConfig my = (MyConfig) ac.getBean("my");
MyConfig my = ac.getBean(MyConfig.class);

System.out.println(my.getUsername().equals(my.getUsername1()));
System.out.println(my.getPassword().equals(my.getPassword1()));

}

}




public void encrypt_MD5() {
String 明文密码 = "123456";
try {
java.security.MessageDigest md = java.security.MessageDigest
.getInstance("MD5");
md.update(明文密码.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer();
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
System.out.println("密文: " + buf.toString());// 32位的加密
System.out.println("密文: " + buf.toString().substring(8, 24));// 16位的加密
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
}
}

MD5加密效果如下:
[img]http://dl2.iteye.com/upload/attachment/0092/6487/cace9f5c-40ed-3d06-a651-0491a2283a61.png[/img]


[url=http://blog.csdn.net/xiaoyusong/article/details/20933]DES对称加密的实现及其源代码[/url]

[url=http://yidinghe.cnblogs.com/articles/449212.html]用 Java 解密 C# 加密的数据(DES)[/url]

[url=http://java.chinaitlab.com/Spring/841847.html]Java文件加密-spring属性文件加密[/url]

[url=http://java.chinaitlab.com/Spring/806481.html]Spring获取Bean的几种方式[/url]
[url=http://lihao312.iteye.com/blog/2078534]MD5,salt,SHA,PBKDF2加密[/url]

备注:本次示例使用的Spring版本是:spring-core-3.2.4.RELEASE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值