2019-11-12
2019-11-12 本文已影响0人
YANG_ad29
springboot 接口参数统一解密
先定义一个加密注解
package com.qlt.common.annotation;
import org.springframework.web.bind.annotation.Mapping;
import java.lang.annotation.*;
/**
* 接口解密
* @author
*
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Mapping
@Documented
public @interface Decrypt {
boolean decode() default true;
}
拦截处理
package com.aaa.common.config;
import com.alibaba.fastjson.JSONObject;
import com.aaa.common.annotation.Decrypt;
import com.aaa.core.web.asset.util.AESEncryption;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
@ControllerAdvice(basePackages = "com.aaa.core.api")
public class DecodeRequestBodyAdvice implements RequestBodyAdvice {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
try {
boolean encode = false;
if (methodParameter.getMethod().isAnnotationPresent(Decrypt.class)) {
Decrypt serializedField = methodParameter.getMethodAnnotation(Decrypt.class);
encode = serializedField.decode();
}
if (encode) {
return new MyHttpInputMessage(httpInputMessage);
}
else{
return httpInputMessage;
}
}catch (Exception e) {
e.printStackTrace();
return httpInputMessage;
}
}
@Override
public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
@Override
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
return o;
}
class MyHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
this.headers = inputMessage.getHeaders();
String s = IOUtils.toString(inputMessage.getBody(), "UTF-8");
String content = JSONObject.parseObject(s).getString("content");
if (null==content){
throw new RuntimeException("参数【content】缺失异常!");
}
try{
this.body = IOUtils.toInputStream(AESEncryption.decrypt(content, AESEncryption.PASSWORD_HOT_APP));
}catch (Exception e){
throw new RuntimeException("解密失败");
}
}
@Override
public InputStream getBody() throws IOException {
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}
}
加解密
package com.aaa.core.web.asset.util;
import org.bitcoinj.core.Base58;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESEncryption {
private static final String TAG = "";
// /** 算法/模式/填充 **/
private static final String CipherMode = "";//CBC
private static final int KeyLength = 128;//128 bits
//TODO arranged key with hot app
public static final String PASSWORD_HOT_APP = "";
//TODO arranged init vector with hot app
private static final String IV_HOT_APP = "";
public static final String WORD_KEY = "";
private static SecretKeySpec createKey(String key) {
byte[] data = null;
if (key == null) {
key = "";
}
StringBuffer sb = new StringBuffer(KeyLength / 8);
sb.append(key);
while (sb.length() < (KeyLength / 8)) {
sb.append("0");
}
if (sb.length() > (KeyLength / 8)) {
sb.setLength(KeyLength / 8);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
private static SecretKeySpec createPasswordKey(String key) {
byte[] data = null;
try {
data = key.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
private static IvParameterSpec createIV(String password) {
byte[] data = null;
if (password == null) {
password = "";
}
StringBuffer sb = new StringBuffer((KeyLength / 8));
sb.append(password);
while (sb.length() < (KeyLength / 8)) {
sb.append("0");
}
if (sb.length() > (KeyLength / 8)) {
sb.setLength((KeyLength / 8));
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new IvParameterSpec(data);
}
private static byte[] encrypt(byte[] content, String password, String iv) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.ENCRYPT_MODE, key, createIV(iv));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] encrypt(byte[] content, String password) {
try {
SecretKeySpec key = createPasswordKey(password);
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Encrypt string return base58 string of the encrypted
*
* @param content
* @param password
* @param iv
* @return
*/
public static String encrypt(String content, String password, String iv) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, password, iv);
String result = Base58.encode(data);
return result;
}
public static String encrypt(String content, String password) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, password);
String result = Base58.encode(data);
return result;
}
private static byte[] decrypt(byte[] content, String password, String iv) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.DECRYPT_MODE, key, createIV(iv));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] decrypt(byte[] content, String password) {
try {
SecretKeySpec key = createPasswordKey(password);
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Decrypt the base58 string of content
*
* @param content
* @param password
* @param iv
* @return
*/
public static String decrypt(String content, String password, String iv) {
byte[] data = null;
try {
data = Base58.decode(content);
} catch (Exception e) {
e.printStackTrace();
}
data = decrypt(data, password, iv);
if (data == null)
return null;
String result = null;
try {
result = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
public static String decrypt(String content, String password) {
byte[] data = null;
try {
data = Base58.decode(content);
} catch (Exception e) {
e.printStackTrace();
}
data = decrypt(data, password);
if (data == null)
return null;
String result = null;
try {
result = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
如果需要把返回值加密可以实现 RequestBodyAdvice