最近开发过程中有一个需求:对webservice接口传输的对象参数的内容进行加密。参考网上的一些AES加密的实例,通过反射读取对象的属性和属性值,加密后反写(解密同理),实现了该功能,具体代码如下:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.SecureRandom;
import java.util.List;
import java.util.Objects;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.axis.encoding.Base64;
public class AESUtil {
private static final String PWD = "pwd2020";
public static final int SECRET_LEVEL_2=128;
public static final int SECRET_LEVEL_3=256;
public static final int SECRET_LEVEL_4=2048;
/**
* 对指定对象的属性值进行加密
*
* @param o
* @return
*/
public static Object encryObject(Object o,int level) {
String[] names = getFiledName(o);
for (String name : names) {
Object value = getFieldValueByName(name, o);
if (value instanceof Object[]) {//数组
for (Object item : (Object[]) value) {
item = encryObject(item,level);
}
}else if (value instanceof List) {//列表
for (Object item : (List) value) {
item = encryObject(item,level);
}
} else if ((value instanceof String) || (value instanceof Integer) || (value instanceof Double)
|| (value instanceof Long) || (value instanceof Float)) {//通用数据类型
value = encrypt((String) value,level);
setFieldValueByName(name, o, value);
} else {//对象
value = encryObject(value,level);
}
}
return o;
}
/**
* 对指定对象的属性值进行解密
*
* @param o
* @return
*/
public static Object decryObject(Object o,int level) {
String[] names = getFiledName(o);
for (String name : names) {
Object value = getFieldValueByName(name, o);
if (value instanceof Object[]) {
for (Object item : (Object[]) value) {
item = decryObject(item,level);
}
}else if (value instanceof List) {
for (Object item : (List) value) {
item = decryObject(item,level);
}
} else if ((value instanceof String) || (value instanceof Integer) || (value instanceof Double)
|| (value instanceof Long) || (value instanceof Float)) {
value = decrypt((String) value,level);
setFieldValueByName(name, o, value);
} else {
value = decryObject(value,level);
}
}
return o;
}
/**
* @desc 获取属性名数组
* @param o
* @return
*/
private static String[] getFiledName(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
fieldNames[i] = fields[i].getName();
}
return fieldNames;
}
/**
* @desc 获取属性的数据类型
* @param fieldName
* @param o
* @return
*/
private static Object getFiledType(String fieldName, Object o) {
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
if (Objects.equals(fieldName, field.getName())) {
return field.getType();
}
}
return null;
}
/**
* @desc 根据属性名获取属性值
* @param fieldName
* @param o
* @return
*/
private static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(o, new Object[] {});
return value;
} catch (Exception e) {
System.err.println("获取属性值失败!" + e);
}
return null;
}
/**
* @desc 根据属性名设置属性值
* @param fieldName
* @param o
* @param value
* @return
*/
private static void setFieldValueByName(String fieldName, Object o, Object value) {
String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try {
Method setMethod = o.getClass().getMethod("set" + methodName, String.class);
// 执行该set方法
setMethod.invoke(o, value);
} catch (Exception e) {
System.err.println("设置属性值" + fieldName + "失败!" + e);
}
}
/**
* 使用AES对数据进行加密
*
* @param content 需要加密的内容
* @param level 加密密钥长度
* @return 加密之后的数据
*/
public static String encrypt(String content,int level) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(level, new SecureRandom(PWD.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return Base64.encode(result);
} catch (Exception e) {
System.err.println("加密失败!" + e);
}
return null;
}
/**
* 使用AES对数据进行解密
*
* @param content 待解密内容
* @param level 解密密钥长度
* @return 解密后的数据
*/
public static String decrypt(String content,int level) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(level, new SecureRandom(PWD.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 创建密码器
byte[] byteContent = Base64.decode(content);
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(byteContent);
return new String(result);
} catch (Exception e) {
System.err.println("解密失败!" + e);
}
return null;
}
}