Spring对JSON请求加解密
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对JSON请求加解密的更多相关文章
- spring cloud config 属性加解密
首先需要(Java Cryptography Extension (JCE))的支持,下载路径: https://www.oracle.com/technetwork/java/javase/down ...
- Spring Boot 实现配置文件加解密原理
Spring Boot 配置文件加解密原理就这么简单 背景 接上文<失踪人口回归,mybatis-plus 3.3.2 发布>[1] ,提供了一个非常实用的功能 「数据安全保护」 功能,不 ...
- spring datasource jdbc 密码 加解密
spring datasource 密码加密后运行时解密的解决办法 - 一号门-程序员的工作,程序员的生活(java,python,delphi实战)http://www.yihaomen.com/a ...
- json串加解密
1.openssl 本身ssl加解密 2.自定义加解密字符串
- 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密
学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA AES RSA AES 混合加密 整合 前言: 为了提高安全性采用了RS ...
- React中的AES加解密请求
引言 在我们使用React开发Web前端的时候,如果是比较大的项目和正常的项目的话,我们必然会用到加解密,之前的文章中提到.NET的一些加解密,那么,这里我就模拟一个例子: 1.后台开发API接口,但 ...
- Spring Cloud Config 配置中心 自动加解密功能 JCE方式
1.首先安装JCE JDK8的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.h ...
- Spring Cloud Config 配置中心 自动加解密功能 jasypt方式
使用此种方式会存在一种问题:如果我配置了自动配置刷新,则刷新过后,加密过后的密文无法被解密.具体原因分析,看 SpringCloud 详解配置刷新的原理 使用 jasypt-spring-boot- ...
- SpringBoot中如何灵活的实现接口数据的加解密功能?
数据是企业的第四张名片,企业级开发中少不了数据的加密传输,所以本文介绍下SpringBoot中接口数据加密.解密的方式. 本文目录 一.加密方案介绍二.实现原理三.实战四.测试五.踩到的坑 一.加密方 ...
随机推荐
- canvas-2lineCap.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 纯CSS绘制mac代码
1.效果图 2.代码 <!doctype html> <html lang="en"> <head> <meta charset=&quo ...
- Archlinux/Manjaro使用笔记-报错:一个或多个 PGP 签名无法校验!的解决方法
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 解决办法:添加无法校验的pgp签名为信任 gpg --recv-keys xxxxxx xxxxxx为无法校验的gpg值
- 【CSS学习】--- overflow属性
一.前言 在网页布局中,未处理的溢出元素绝对算得上是个“毒瘤”.因为如果一个“盒子”周围还有其它元素,而从这个盒子中溢出的元素会和盒子周围的元素发生层叠,并脱离了整个HTML元素,所以我们应当合理使用 ...
- csharp: Configuring ASP.NET with Spring.NET and FluentNHibernate
Domain: FluentNhibernateLocalSessionFactoryObject.cs using System; using System.Collections.Generic; ...
- 使用Topshelf创建自宿主的Windows服务程序
在传统的Windows服务开发过程中,需要添加一个服务安装程序,里面写安装,启动和停止服务等逻辑.现在,使用TopSelf可以简化这个过程.具体请看官网说明: http://docs.topshelf ...
- Flutter 布局(六)- SizedOverflowBox、Transform、CustomSingleChildLayout详解
本文主要介绍Flutter布局中的SizedOverflowBox.Transform.CustomSingleChildLayout三种控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析. ...
- [HDFS_4] HDFS 的 Java 应用开发
0. 说明 在 IDEA下 进行 HDFS 的 Java 应用开发 通过编写代码实现对 HDFS 的增删改查操作 1. 流程 1.1 在项目下新建 Moudle 略 1.2 为 Moudle 添加 M ...
- windows防火墙安全设置指定ip访问指定端口
场景摘要: 1.我有三台腾讯云服务器 2.我日常办公网络的ip换了 3.我在腾讯云上面改了安全规则,也不能访问我A服务器的21,1433等端口 4.开始我以为是办公网络的安全设置问题 5.我进B服务器 ...
- 【PAT】B1056 组合数的和(15 分)
就看着代码量一直到没什么好说的了 #include<stdio.h> int main(){ int N,K;scanf("%d",&N); int sum=0 ...