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中接口数据加密.解密的方式. 本文目录 一.加密方案介绍二.实现原理三.实战四.测试五.踩到的坑 一.加密方 ...
随机推荐
- Raspberrypi 3B+ 安装 php+sqlite
按照网上的命令都为安装php5-fpm 和 php5-sqlite, 但是发现无法找到软件,可能是系统版本比较高的缘故,原来的版本已经不支持了. 经过努力华找到如下安装方法 sudo apt-get ...
- Flash饼状图统计代码
index.html文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- 【实践练习一】Git以及Github的使用
以前经常在同学大神那听说过Github这神器,虽敬佩久已,奈何却无缘使用.好吧,我承认,主要还是不会用,一看网站全是英文的,想想还是不要为难自己了.然而现在还是要为难自己了,趁着早上刚学 ...
- 洛谷P1742 最小圆覆盖(计算几何)
题意 题目链接 Sol 暴力做法是\(O(n^3)\)枚举三个点然后check一下是否能包含所有点 考虑一种随机算法,首先把序列random_shuffle一下. 然后我们枚举一个点\(i\),并维护 ...
- mybatis 中between and用法
今天遇到一个问题,半天没看出来问题,特意记录一下 Dao ConfigEvaluation findConfigEvaluationByEvalpecent(BigDecimal evalPercen ...
- 网页一键加入QQ群
三步简单实现功能:网页提供加入qq群按钮 让他人一键加入qq群 第一步:进入qq群官网:http://qun.qq.com/join.html 第二步:选择需要加入的群并生成网页代码 第三步:在网页 ...
- Nginx下配置网站SSL实现https访问本站就是用的这方法
本文出至:新太潮流网络博客 第一步:服务器环境,lnmp即Linux+Nginx+PHP+MySQL,本文中以我的博客为例,使用的是阿里云最低档的ECS+免费的Linux服务器管理系统WDCP快速搭建 ...
- [MapReduce_7] MapReduce 中的排序
0. 说明 部分排序 && 全排序 && 采样 && 二次排序 1. 介绍 sort 是根据 Key 进行排序 [部分排序] 在每个分区中,分别进行排序 ...
- Matplotlib:tick_params参数设置
1.tick_params语法 参数:axis : {‘x’, ‘y’, ‘both’} Axis on which to operate; default is ‘both’.reset : boo ...
- 反射型XSS+文件上传+CSRF—DVWA
在学习的过程中,想到将几种漏洞进行组合练习,记录下学习过程.大佬请绕过!谢谢!! 测试环境:DVWA,安装方法参考上一篇:https://www.cnblogs.com/aq-ry/p/9220584 ...