Spring對JSON請求加解密
http://blog.csdn.net/jing956899449/article/details/54315048
Spring中處理JSON請求通常使用@RequestBody和@ResponseBody註解,針對JSON請求加解密和過濾字串,Spring提供了RequestBodyAdvice和ResponseBodyAdvice兩個介面
具體使用1、解密:
import com.hive.util.AESOperator;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.hive")
public class MyRequestBodyAdvice implements RequestBodyAdvice {
private final static Logger logger = LoggerFactory.getLogger(MyResponseBodyAdvice.class);
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
try {
return new MyHttpInputMessage(inputMessage);
} catch (Exception e) {
e.printStackTrace();
return inputMessage;
}
}
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return body;
}
class MyHttpInputMessage implements HttpInputMessage {
private HttpHeaders headers;
private InputStream body;
public MyHttpInputMessage(HttpInputMessage inputMessage) throws Exception {
this.headers = inputMessage.getHeaders();
this.body = IOUtils.toInputStream(AESOperator.getInstance().decrypt(IOUtils.toString(inputMessage.getBody(), "UTF-8")), "UTF-8");
}
@Override
public InputStream getBody() throws IOException {
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}
}
- 2、加密:
package com.hive.core.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hive.util.AESOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 返回資料加密
*/
@ControllerAdvice(basePackages = "com.hive")
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
private final static Logger logger = LoggerFactory.getLogger(MyResponseBodyAdvice.class);
private final static String KEY = "!QA2Z@w1sxO*(-8L";
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
boolean encode = false;
if (returnType.getMethod().isAnnotationPresent(SerializedField.class)) {
//獲取註解配置的包含和去除欄位
SerializedField serializedField = returnType.getMethodAnnotation(SerializedField.class);
//是否加密
encode = serializedField.encode();
}
if (encode) {
logger.info("對方法method :" + returnType.getMethod().getName() + "返回資料進行加密");
ObjectMapper objectMapper = new ObjectMapper();
try {
String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);
return AESOperator.getInstance().encrypt(result);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return body;
}
}
註解類:
package com.hive.core.json;
import org.springframework.web.bind.annotation.Mapping;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface SerializedField {
/**
* 是否加密
* @return
*/
boolean encode() default true;
}
預設是true,我這邊使用false。註解類中還可以定義需要過濾的字串
AES加密類
package com.hive.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES CBC加密
*/
public class AESOperator {
/*
* 加密用的Key 可以用26個字母和數字組成 此處使用AES-128-CBC加密模式,key需要為16位。
*/
private String KEY = "!QA2Z@w1sxO*(-8L";
private String VECTOR = "!WFNZFU_{H%M(S|a";
private static AESOperator instance = null;
private AESOperator() {
}
public static AESOperator getInstance() {
return Nested.instance;
}
//於內部靜態類只會被載入一次,故該實現方式時執行緒安全的!
static class Nested {
private static AESOperator instance = new AESOperator();
}
/**
* 加密
*
* @param content
* @return
* @throws Exception
*/
public String encrypt(String content) throws Exception {
return encrypt(content, KEY, VECTOR);
}
/**
* 加密
*
* @param content
* @return
* @throws Exception
*/
public String encrypt(String content,String key) throws Exception {
return encrypt(content, key, VECTOR);
}
/**
* 加密
*
* @param content
* @param key
* @param vector
* @return
* @throws Exception
*/
public String encrypt(String content, String key, String vector) throws Exception {
if (key == null) {
return null;
}
if (key.length() != 16) {
return null;
}
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一個向量iv,可增加加密演算法的強度
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
return new BASE64Encoder().encode(encrypted);// 此處使用BASE64做轉碼。
}
/**
* 解密
*
* @param content
* @return
* @throws Exception
*/
public String decrypt(String content) throws Exception {
return decrypt(content, KEY, VECTOR);
}
/**
* 解密
*
* @param content
* @return
* @throws Exception
*/
public String decrypt(String content,String key) throws Exception {
return decrypt(content, key, VECTOR);
}
/**
* 解密
*
* @param content
* @param key
* @param vector
* @return
* @throws Exception
*/
public String decrypt(String content, String key, String vector) throws Exception {
try {
if (key == null) {
return null;
}
if (key.length() != 16) {
return null;
}
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec iv = new IvParameterSpec(vector.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(content);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "UTF-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
public static void main(String[] args) throws Exception {
// 需要加密的字串
String cSrc = "我愛你";
// 加密
long lStart = System.currentTimeMillis();
String enString = AESOperator.getInstance().encrypt(cSrc,"!QA2Z@w1sxO*(-8L");
System.out.println("加密後的字串是:" + enString);
long lUseTime = System.currentTimeMillis() - lStart;
System.out.println("加密耗時:" + lUseTime + "毫秒");
// 解密
lStart = System.currentTimeMillis();
String DeString = AESOperator.getInstance().decrypt(enString);
System.out.println("解密後的字串是:" + DeString);
lUseTime = System.currentTimeMillis() - lStart;
System.out.println("解密耗時:" + lUseTime + "毫秒");
}
}
相關文章
- 如何在Spring Boot中驗證JSON請求內容? - SeunSpring BootJSON
- Spring Security 前後端分離登入,非法請求直接返回 JSONSpring後端JSON
- MIME.json 檔案請求 字尾/響應型別 對照表JSON型別
- C#模擬HTTP請求Post JSONC#HTTPJSON
- vue3.0 請求本地json 檔案VueJSON
- spring cloud gateway 原始碼解析(3)記錄請求引數及返回的jsonSpringCloudGateway原始碼JSON
- 【Postman】6 Postman 傳送post請求-Json格式PostmanJSON
- 如何根據介面請求型別和請求方法,自動執行對應請求型別
- web開發安全之請求及返回流資料加解密實踐Web解密
- spring mvc中獲取請求URLSpringMVC
- jmeter之傳送json資料的post請求JMeterJSON
- go語言請求http介面示例 並解析jsonGoHTTPJSON
- nodejs庫express是如何接收inbound json請求的NodeJSExpressJSON
- STM32以JSON格式釋出HTTP請求JSONHTTP
- java 請求HTTP返回json集合,物件處理方式JavaHTTPJSON物件
- RequestMappingHandlerMapping請求地址對映流程!APP
- java操作http請求針對不同提交方式(application/json和application/x-www-form-urlencoded)JavaHTTPAPPJSONORM
- 十、Spring Boot整合Spring Security之HTTP請求授權Spring BootHTTP
- 使用Spring Integration接收TCP與UDP請求SpringTCPUDP
- spring boot請求字尾匹配的操作Spring Boot
- Spring MVC的請求處理邏輯SpringMVC
- go對get、post請求封裝Go封裝
- dio+json_serializable從網路請求到資料解析JSON
- unity3d c# http 請求json資料解析Unity3DC#HTTPJSON
- shell請求api,獲取json返回值,做判斷APIJSON
- PHP與Curl採用的GET,POST,JSON方式請求APIPHPJSONAPI
- SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。SpringMVCdelete
- Spring MVC能響應HTTP請求的原因?SpringMVCHTTP
- 對稱EDS加解密方法解密
- Spring boot 與 json_schema ,請求和響應 校驗Spring BootJSON
- Vue-cli 使用json server在本地模擬請求資料VueJSONServer
- Flutter基礎(十一)網路請求(Dio)與JSON資料解析FlutterJSON
- Flutter 基礎(十一)網路請求(Dio)與 JSON 資料解析FlutterJSON
- 請求OpenFeign的GET請求時,請求為何失敗?
- Spring MVC框架處理Web請求的基本流程SpringMVC框架Web
- Spring Cloud Gateway 之 請求應答日誌列印SpringCloudGateway
- spring security:ajax請求的session超時處理SpringSession
- 說說如何使用 Spring Security 保護 web 請求SpringWeb