Springboot实现接口传输加解密
前言
先给大家看下效果,原本我们的请求是这样子的

加密后的数据传输是这样子的

加解密步骤:
1.前端请求前进行加密,然后发送到后端
2.后端收到请求后解密
3.后端返回数据前进行加密
4.前端拿到加密串后,解密数据
加解密算法:
本文用的是国密算法作为参考,当然大家也可以用其它算法进行加解密
国密算法加解密可参照:java/vue使用国密sm2进行数据加密_vue sm2_qq243920161的博客-CSDN博客java/vue使用国密sm2https://blog.csdn.net/qq243920161/article/details/127865091
一、前端请求前进行加密,然后发送到后端
import axios from 'axios';
import { sm2 } from 'sm-crypto';axios.interceptors.request.use(config => {// form-data传参方式不加密if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {return;}// 非body方式传参,不加密if (config.data) {return;}// 使用国密算法进行加密let encryptData = sm2.doEncrypt(JSON.stringify(config.data), '加密公钥,请提前生成好');config.data = {data: encryptData}
});
以上代码使用了axios拦截器,对所有请求进行拦截,拦截器里,使用config.data获取到请求的body进行加密,加密后,把加密后的数据重新赋值到config.data,sm-crypto是国密算法的依赖,使用前npm install sm-crypto即可
请确保config.data是一个对象或者数组,不要是一个字符串,否则后端获取body时会失败
加密成功后,从network就能看到加密的数据了

二、后端收到请求后解密
这里有两个类直接复制粘贴即可,一个是RequestWrapper,这个类是用来读取body的,一个是BodyRequestWrapper,这个类是用来解密后,将解密后的数据封装到request,供Controller层使用,这里直接上代码了
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;/*** 用来读取body*/
public class RequestWrapper extends HttpServletRequestWrapper {private final String body;public RequestWrapper(HttpServletRequest request) {super(request);StringBuilder stringBuilder = new StringBuilder();BufferedReader bufferedReader = null;InputStream inputStream = null;try {inputStream = request.getInputStream();if (inputStream != null) {bufferedReader = new BufferedReader(new InputStreamReader(inputStream));char[] charBuffer = new char[128];int bytesRead = -1;while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {stringBuilder.append(charBuffer, 0, bytesRead);}} else {stringBuilder.append("");}} catch (IOException ex) {} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}}}body = stringBuilder.toString();}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());ServletInputStream servletInputStream = new ServletInputStream() {@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() throws IOException {return byteArrayInputStream.read();}};return servletInputStream;}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(this.getInputStream()));}public String getBody() {return this.body;}
}
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;/*** 用来重新封装request*/
public class BodyRequestWrapper extends HttpServletRequestWrapper {/*** 存放JSON数据主体*/private String body;public BodyRequestWrapper(HttpServletRequest request, String context) {super(request);body = context;}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));return new ServletInputStream() {@Overridepublic int read() throws IOException {return byteArrayInputStream.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener listener) {}};}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(this.getInputStream()));}
}
然后我们需要写一个请求过滤器,继承Filter,对所有请求接口进行过滤
import com.alibaba.fastjson2.JSON;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** 请求加解密过滤器** @author 猴哥*/
@Component
public class RequestHandler implements Filter {/*** 进行请求加密*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// form-data不校验if ("application/x-www-form-urlencoded".equals(request.getContentType())) {chain.doFilter(request, response);return;}// 拿到加密串String data = new RequestWrapper((HttpServletRequest) request).getBody();if (StringUtils.isEmpty(data)) {chain.doFilter(request, response);return;}// 解析String body = Sm2Util.decrypt("解密私钥", data);request = new BodyRequestWrapper((HttpServletRequest) request, body);chain.doFilter(request, response);}
}
Sm2Util是国密的解密方式,工具类在之前分享的帖子里有,当然,大家可以用自己喜欢的方式进行加解密
java/vue使用国密sm2进行数据加密_vue sm2_qq243920161的博客-CSDN博客java/vue使用国密sm2https://blog.csdn.net/qq243920161/article/details/127865091
这样就能拿到加密串了

但是有个问题就是,这样写的话,所有请求都会走Filter,但是我们只想让部分请求走Filter怎么办呢,写一个配置类就可以了,这样就可以将url进行过滤
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author 猴哥*/
@Configuration
public class EncryptionConfiguration {/*** 过滤器配置*/@Beanpublic FilterRegistrationBean<RequestHandler> filterRegistration(RequestHandler requestHandler) {FilterRegistrationBean<RequestHandler> registration = new FilterRegistrationBean<>();registration.setFilter(requestHandler);registration.addUrlPatterns("/plugin/*");registration.setName("encryptionFilter");//设置优先级别registration.setOrder(1);return registration;}
}
以上代码就是将/plugin开头的url进行拦截,代码不难,就不用过多解释了吧
三、后端返回数据前进行加密
代码如下
import com.alibaba.fastjson.JSON;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;/*** 响应加解密拦截器** @author 猴哥*/
@Component
@ControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice<Object> {/*** 返回true,才会走beforeBodyWrite方法*/@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {return true;}/*** 响应加密*/@Overridepublic Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse serverHttpResponse) {// 拿到响应的数据String json = JSON.toJSONString(body);// 进行加密return Sm2Util.encrypt("加密公钥", json);}
}
前端即可拿到这样一个加密数据

四、前端拿到加密串后,解密数据
需要再axios中添加一个响应拦截器,代码如下
import axios from 'axios';
import { sm2 } from 'sm-crypto';// 响应拦截器
axios.interceptors.response.use(res => {res.data = JSON.parse(sm2.doDecrypt(res.data, '解密私钥'));console.log('解密出来的数据', res.data);
});
打印如图所示

相关文章:
Springboot实现接口传输加解密
前言 先给大家看下效果,原本我们的请求是这样子的 加密后的数据传输是这样子的 加解密步骤: 1.前端请求前进行加密,然后发送到后端 2.后端收到请求后解密 3.后端返回数据前进行加密 4.前端拿到加密串后,解密数据 加解密算法&…...
TypeScript类型系统:强类型的优势和使用方式
目录 引言强类型的优势更好的代码可读性更好的代码可维护性更好的代码重构能力更好的代码可靠性更好的代码重用能力 使用方式声明变量类型函数参数和返回值类型类型别名泛型类型(了解) 总结 引言 在上一篇文章《TypeScript入门指南:从JS到TS的…...
有没有可以代替风铃系统的专业问卷工具?
风铃系统问卷是一种流行的调查和数据分析工具,已广泛应用于学术研究、市场营销和社会科学。然而,有几种替代产品提供了与风铃系统类似的特性和功能,可以被企业用来进行调查和分析数据。在这篇文章中,我们将介绍风铃系统的十大替代…...
【数字调制】数字调制技术FSK与PSK分析与研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
html实现好看的个人介绍,个人主页模板4(附源码)
文章目录 1.设计来源1.1 主界面1.2 我的文章界面1.3 我的相册界面1.4 关于我界面1.5 联系我界面 2.效果和源码2.1 动态效果2.2 源代码2.2 源代码目录 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131265259 …...
内存不够用,那你的内存去哪了?
一、前言 近几年开发了一些大型的应用程序,在程序性能调优或者解决一些疑难杂症问题的过程中,遇到最多的还是与内存相关的一些问题。例如glibc内存分配器ptmalloc,google的内存分配器tcmalloc都存在“内存泄漏”,即内存不归还操作…...
哈希表--day4--(leetcode202/leetcode1/leetcode454)
文章目录 leetcode202. 快乐数基本思路AC-code leetcode1. 两数之和基本思路AC-code 454.四数相加II基本思路AC-code leetcode202. 快乐数 链接 基本思路 实际上题目隐藏着一个小细节,就是告诉你会发生无限循环,那我们该如何跳出这个无限循环就是一个…...
基于Python+Django+mysql+html通讯录管理系统
基于PythonDjangomysqlhtml通讯录管理系统 一、系统介绍二、功能展示1.用户登陆2.用户注册3.密码修改4.查询5.添加6.修改7.删除 三、其它系统四、获取源码 一、系统介绍 该系统实现了 用户登陆、用户注册、密码修改、查询信息、添加信息,修改信息、删除信息 运行环…...
Rabbitmq学习
文章目录 前言RabbitMQ 1 同步调用和异步调用2 常见的MQ对比3 安装RabbitMQ4 RabbitMQ学习4.1 helloworld学习 5 Spring AMQP5.1 AMQP的入门案例(使用rabbittemplate进行消息发送和接受)5.2 RabbitMQ的workquene5.3 发布订阅模型(exchange(广播fanout 路由direct 话题topic))5.…...
初识轻量级分布式任务调度平台 xxl-job
文章目录 前言xxl-job的目录结构项目依赖 (父 pom.xml)xxl-job-admin 启动xxl-job-executor-sample (项目使用示例)xxl-job-executor-sample-frameless : 不使用框架的接入方式案例xxl-job-executor-sample-springboot : springboot接入方案案例 xxl-job执行器器启动流程分析调…...
web 语音通话 jssip
先把封装好的地址安上(非本人封装):webrtc-webphone: 基于JsSIP开发的webrtc软电话 jssip中文文档:jssip中文开发文档(完整版) - 简书 jssip使用文档:(我没有运行过,但…...
随风摇曳的她——美蕨(matlab实现)
目录 1 随风摇曳的她 2 摇曳带来的哲思 3 Matlab代码实现 1 随风摇曳的她 梦幻的场景、浪漫的气息,带上心爱的人,拥抱在这片花海之下,便有了电影男女主角的氛围感; 就算阅尽了世间风貌,也抵不上和她在一起时锦短情长&a…...
时序数据库的流计算支持
一、时序数据及其特点 时序数据(Time Series Data)是基于相对稳定频率持续产生的一系列指标监测数据,比如一年内的道琼斯指数、一天内不同时间点的测量气温等。时序数据有以下几个特点: 历史数据的不变性数据的有效性数据的时效…...
springboot启动流程 (3) 自动装配
在SpringBoot中,EnableAutoConfiguration注解用于开启自动装配功能。 本文将详细分析该注解的工作流程。 EnableAutoConfiguration注解 启用SpringBoot自动装配功能,尝试猜测和配置可能需要的组件Bean。 自动装配类通常是根据类路径和定义的Bean来应…...
ansible-roles模块
roles用于层次性,结构化地组织playbook,roles能够根据层次型结构自动装载变量文件,tasks以及handlers等。要使用只要载playbook中使用include指令引入即可。 (roles就是通过分别将变量,文件,任务ÿ…...
聊聊我做 NeRF-3D重建性能优化经历
我们新推出大淘宝技术年度特刊《长期主义,往往从一些小事开始——工程师成长总结专题》,专题收录多位工程师真诚的心路历程与经验思考,覆盖终端、服务端、数据算法、技术质量等7大技术领域,欢迎一起沟通交流。 本文为此系列第四篇…...
未磁科技全球首台64通道无液氦心磁图仪及首个培训基地落户北京安贞医院
【全球首台64通道无液氦心磁图仪在北京安贞医院举行开机仪式】 近日,在北京安贞医院举行了未磁科技全球首台64通道无液氦心磁图仪开机仪式,中国医学装备协会赵自林理事长、北京安贞医院纪智礼书记、张宏家院长、宋现涛教授,以及未磁科技蔡宾…...
SpringBoot 如何使用 ApplicationEventPublisher 发布事件
SpringBoot 如何使用 ApplicationEventPublisher 发布事件 在 SpringBoot 应用程序中,我们可以使用 ApplicationEventPublisher 接口来发布事件。事件可以是任何对象,当该对象被发布时,所有监听该事件的监听器都会收到通知。 下面是一个简单…...
【深度学习】2-3 神经网络-输出层设计
前馈神经网络(Feedforward Neural Network),之前介绍的单层感知机、多层感知机等都属于前馈神经网络,它之所以称为前馈(Feedforward),或许与其信息往前流有关:数据从输入开始,流过中间计算过程,最后达到输出…...
Python网络爬虫开发:使用PyQt5和WebKit构建可定制的爬虫
部分数据来源:ChatGPT 引言 在网络爬虫开发中,使用Web浏览器模拟用户行为是非常重要的。而在这个过程中,基于 WebKit 的框架可以提供比其他技术更紧密的浏览器集成,以及更高效、更多样化的页面交互方式。 在本文中,我们将通过一个使用基于 WebKit 的爬虫示例,并与类似…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
