对接口部分字段进行加解密
1. 场景
要求对接口中部分输入和输出参数进行加解密。如密码要求前端加密后传给后端进行解密。
2.解决方案
为了减少代码的侵入,采用注解形式进行处理。
/** * 进行参数解密
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecryptField {
String algorithm() default "AES";
}
/**
* 进行参数加密
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EncryptField {
String algorithm() default "AES";
}
package org.api.web.crypto;import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Objects;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.api.utils.EncryptUtils;
import org.springframework.core.annotation.AnnotationUtils;
public class CryptAnnotationHandler {
private final static Logger logger = LogManager.getLogger(CryptAnnotationHandler.class);
@SuppressWarnings("unchecked")
public static void handle(Object e) {
if (e instanceof Collection) {
Collection<Object> objects = (Collection<Object>) e;
for (Object object : objects) {
try {
endecryptObject(object);
} catch (Exception e1) {
logger.error("加解密出错");
}
}
} else {
try {
endecryptObject(e);
} catch (Exception e1) {
logger.error("加解密出错");
}
}
}
/**
* 只支持最一层会字符串的才可以加解密操作
*
* @param requestObj
* @throws IllegalAccessException
*/
private static void endecryptObject(Object requestObj) throws Exception {
if (Objects.isNull(requestObj)) {
return;
}
Field[] fields = requestObj.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getType().equals(String.class)) {
// 若该字段被EncryptField注解,则进行解密
DecryptField deAnnotation = AnnotationUtils.findAnnotation(field, DecryptField.class);
if (null != deAnnotation) {
// 设置private类型允许访问
field.setAccessible(Boolean.TRUE);
if(AlgorithmEnum.DES.getCode().equals(deAnnotation.algorithm())){
field.set(requestObj, EncryptUtils.encryptByDes((String) field.get(requestObj)));
}else if(AlgorithmEnum.AES.getCode().equals(deAnnotation.algorithm())){
field.set(requestObj, EncryptUtils.encryptByAes((String) field.get(requestObj)));
}else{
throw new NoSupportEncryptTypeException("不支持算法:"+deAnnotation.algorithm());
}
field.setAccessible(Boolean.FALSE);
}
EncryptField enAnnotation = AnnotationUtils.findAnnotation(field, EncryptField.class);
if (null != enAnnotation) {
// 设置private类型允许访问
field.setAccessible(Boolean.TRUE);
if(AlgorithmEnum.DES.getCode().equals(enAnnotation.algorithm())){
field.set(requestObj, EncryptUtils.encryptByDes((String) field.get(requestObj)));
}else if(AlgorithmEnum.AES.getCode().equals(enAnnotation.algorithm())){
field.set(requestObj, EncryptUtils.encryptByAes((String) field.get(requestObj)));
}else{
throw new NoSupportEncryptTypeException("不支持算法:"+enAnnotation.algorithm());
}
field.setAccessible(Boolean.FALSE);
}
} else {
throw new NoSupportEncryptTypeException("不支持");
}
}
}
}
public class EncryptUtils { private static Logger logger = LoggerFactory.getLogger(EncryptUtils.class);
public static final String KEY = "xxxxxx";
private static final String CHARSET_UTF8 = "UTF-8";
/**
* 算法
*/
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* 参考Java Cryptography Architecture Standard Algorithm Name Documentation
*
* @param text
* @param encodingAlgorithm
* @return
*/
public static String encrypt(String text, String algorithm) {
if (text == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(text.getBytes());
return Hex.encodeHexString(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
logger.error("加密异常,无此算法", e);
return null;
}
}
/**
* 参考Java Cryptography Architecture Standard Algorithm Name Documentation
* 默认是MD5
*
* @param text
* @param encodingAlgorithm
* @return
*/
public static String encryptByMd5(String raw) {
return encrypt(raw, "MD5");
}
/**
* sha 加密
* @param raw
* @return
*/
public static String encryptBySha(String raw) {
return encrypt(raw, "SHA-256");
}
/**
* aes 加密
* @param raw
* @return
*/
public static String encryptByAes(String raw) {
return encryptByAes(raw, KEY);
}
/**
* aes 解密
* @param raw
* @return
*/
public static String decryptByAes(String raw) {
return decryptByAes(raw, KEY);
}
/**
* des 加密
* @param raw
* @return
*/
public static String encryptByDes(String raw) {
return encryptByDes(raw, KEY);
}
/**
* des 解密
* @param raw
* @return
*/
public static String decryptByDes(String raw) {
return decryptByDes(raw, KEY);
}
/**
* AES加密
*
* @param content
* @param encryptKey
* @return
*/
public static String encryptByAes(String content, String encryptKey) {
if(StringUtils.isEmpty(content)){
return null;
}
try {
byte[] bytes = encryptKey.getBytes(CHARSET_UTF8);
SecretKeySpec keySpec = new SecretKeySpec(bytes, "AES");
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] bytes1 = cipher.doFinal(content.getBytes(CHARSET_UTF8));
String result = new String(Base64.encodeBase64(bytes1));
return result;
} catch (Exception e) {
logger.error("AES编码异常", e);
}
return null;
}
public static String decryptByAes(String content, String encodeRule) {
if(StringUtils.isEmpty(content)){
return null;
}
byte[] decode = Base64.decodeBase64(content);
try {
SecretKeySpec keySpec = new SecretKeySpec(encodeRule.getBytes(CHARSET_UTF8), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] bytes = cipher.doFinal(decode);
return new String(bytes, CHARSET_UTF8);
} catch (Exception e) {
logger.error("AES解码异常", e);
}
return null;
}
private static byte[] encryptByDes(byte[] src, byte[] key) throws Exception {
SecureRandom sr = new SecureRandom();
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
return cipher.doFinal(src);
}
private static byte[] decryptByDes(byte[] src, byte[] key) throws Exception {
SecureRandom sr = new SecureRandom();
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
return cipher.doFinal(src);
}
/**
* Des 解密
*/
public static String decryptByDes(String src, String key) {
String decryptStr = "";
try {
byte[] decrypt = decryptByDes(hex2byte(src.getBytes()), key.getBytes());
decryptStr = new String(decrypt);
} catch (Exception e) {
e.printStackTrace();
}
return decryptStr;
}
/**
* Des 加密
*/
public static String encryptByDes(String src, String key){
byte[] bytes = null;
String encryptStr = "";
try {
bytes = encryptByDes(src.getBytes(), key.getBytes());
} catch (Exception ex) {
ex.printStackTrace();
}
if (bytes != null)
encryptStr = byte2hex(bytes);
return encryptStr;
}
private static byte[] hex2byte(byte[] b) {
if ((b.length % 2) != 0)
throw new IllegalArgumentException("length not even");
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
String item = new String(b, n, 2);
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
return b2;
}
private static String byte2hex(byte[] b) {
String hs = "";
String temp = "";
for (int n = 0; n < b.length; n++) {
temp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (temp.length() == 1)
hs = hs + "0" + temp;
else
hs = hs + temp;
}
return hs.toUpperCase();
}
参考: https://gitee.com/pengchua/restapi/tree/master/openapi
以上是 对接口部分字段进行加解密 的全部内容, 来源链接: utcz.com/z/517800.html