1.引入aop依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.自定义注解,使用Aspect 对传入数据加密,出参解密
/**
* @author zhenglong
* @Description: DESC加解密字段
* @Date 2020/11/26 9:32
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface EnDeField {
/**
* 1 desc 、 2 md5和desc
* @return
*/
int value() default 1;
}
3.编写Aop,实现注解类添加到方法和对应的字段上,可以进行自动加解密
/**
* @author zhenglong
* @Description: 安全字段加密解密切面
* @Date 2020/11/26 0:12
*/
@Aspect
@Component("EndeFieldAspect")
public class EnDeFieldAop {
Logger log = LoggerFactory.getLogger(EnDeFieldAop.class);
// @Pointcut("execution(* com.csair.cargo.delivery.exchange.controller.*.*(..)) ")
// public void annotationPointCut() {
// }
@Around("execution(* com.csair.cargo.delivery.exchange.controller.*.*(..)) && @annotation(enDeField)")
public Object around(ProceedingJoinPoint joinPoint,EnDeField enDeField) {
Object responseObj = null;
try {
Object requestObj = null;
try {
requestObj = joinPoint.getArgs()[0];
} catch (Exception e) {
}
handleEncrypt(requestObj);
responseObj = joinPoint.proceed();
handleDecrypt(responseObj);
} catch (NoSuchMethodException e) {
e.printStackTrace();
log.info("加解密出现问题了", e.getMessage());
} catch (Throwable throwable) {
log.info("加解密出现问题了", throwable.getCause());
// throwable.printStackTrace();
}
return responseObj;
}
/**
* 处理加密
*
* @param requestObj
*/
private void handleEncrypt(Object requestObj) throws Exception {
if (Objects.isNull(requestObj)) {
return;
}
authField(requestObj, 1);
}
/**
* 处理解密
*
* @param responseObj
*/
private Object handleDecrypt(Object responseObj) throws Exception {
if (Objects.isNull(responseObj)) {
return null;
}
@SuppressWarnings("rawtypes")
ExecuteResult executeResult = (ExecuteResult) responseObj;
Object o = executeResult.getResult();
if (o instanceof PageResult) {
@SuppressWarnings("rawtypes")
PageResult pageResult = (PageResult) o;
List list = pageResult.getData();
forList(list, 2);
} else if (o instanceof Collection) {
List list = (List) o;
forList(list, 2);
} else {
authField(o, 2);
}
return responseObj;
}
private Object forList(List list, Integer flag) throws Exception {
if (CollectionUtils.isEmpty(list)) {
return null;
}
for (Object r : list) {
authField(r, flag);
}
return list;
}
/**
* 公共加解密方法
*
* @param o
* @throws Exception
*/
private void authField(Object o, Integer flag) throws Exception {
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
boolean hasSecureField = field.isAnnotationPresent(EnDeField.class);
if (hasSecureField) {
field.setAccessible(true);
String encryptValue = (String) field.get(o);
//int value = field.getAnnotation(EnDeField.class).value();
String plaintextValue = null;
if (encryptValue == null) {
continue;
}
if (flag == 1) {
plaintextValue = DescUtils.encrypt(encryptValue);
} else {
plaintextValue = DescUtils.decrypt(encryptValue);
}
field.set(o, plaintextValue);
}
}
}
}
4.附上DESC根据公钥和向量加解密工具类
/**
* @author zhenglong
* @Description: DESC加解密utils
* @Date 2020/11/25 19:17
*/
public class DescUtils {
/**
* 字节数组转16进制
* @param bytes 需要转换的byte数组
* @return 转换后的Hex字符串
*/
public static String bytesToHex(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if(hex.length() < 2){
sb.append(0);
}
sb.append(hex);
}
return sb.toString();
}
/**
* 解密数据
* @param message
* @return
* @throws Exception
*/
public static String decrypt(String message) throws Exception {
// 传入加密串,转成bash64字符串
byte[] bytes = Base64.decodeBase64(message);
// 传入byte数组常量,返回16进制字符串,并全部转大写,得到byte数组常量的16进制大写字符串
String pkey = bytesToHex(DescConstant.key).toUpperCase();
DESKeySpec desKeySpec = new DESKeySpec(pkey.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DescConstant.desc);
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(DescConstant.ivKey);
Cipher cipher = Cipher.getInstance(DescConstant.descFlag);
cipher.init(Cipher.DECRYPT_MODE, secretKey,iv);
byte[] retByte = cipher.doFinal(bytes);
return new String(retByte, DescConstant.encode).trim();
}
/**
* 加密数据
* @param message
* @return
* @throws Exception
*/
public static String encrypt(String message) throws Exception {
Cipher cipher = Cipher.getInstance(DescConstant.descFlag );
String pkey = bytesToHex(DescConstant.key).toUpperCase();
DESKeySpec desKeySpec = new DESKeySpec(pkey.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DescConstant.desc);
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(DescConstant.ivKey);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,iv);
byte[] bytes = cipher.doFinal(message.getBytes(DescConstant.encode));
return Base64.encodeBase64String(bytes);
}
/**
* Hex字符串转byte
* @param inHex 待转换的Hex字符串
* @return 转换后的byte
*/
public static byte hexToByte(String inHex){
return (byte)Integer.parseInt(inHex,16);
}
}