Spring Boot 一个注解搞定「加密 + 解密 + 签名 + 验签」

Spring Boot 一个注解搞定「加密 + 解密 + 签名 + 验签」

本文基于 Spring Boot 3.x,通过一个自定义注解 + AOP,一行注解即可给任何 Controller 方法加上
请求解密 → 验签 → 响应加密 → 加签 的完整链路,并可直接拷贝到生产环境使用。

一、最终效果

@PostMapping("/order")
@ApiSecurity(decryptRequest = true, encryptResponse = true)   // ← 就这么一行
public OrderResp createOrder(@RequestBody OrderReq req) {return service.create(req);
}
  • 请求体:RSA 加密后的 AES 密钥 + AES 加密后的业务 JSON + 签名
  • 框架自动完成 解密 → 验签 → 业务处理 → 响应加密 → 加签
  • 零侵入,老接口想加安全,贴一个注解即可。

二、传输对象

@Data
public class ApiSecurityParam {private String appId;      // 应用标识private String key;        // RSA 加密后的 AES 密钥(Base64)private String data;       // AES 加密的业务 JSON(Base64)private String sign;       // 签名private String timestamp;  // 防重放private String nonce;      // 防重放
}

三、核心注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiSecurity {boolean decryptRequest()  default false; // 请求体是否解密boolean encryptResponse() default false; // 响应体是否加密boolean sign()            default true;  // 是否验签/加签
}

四、AOP 切面(RequestBodyAdvice + ResponseBodyAdvice)

同时解决 InputStream 只能读一次 的问题。

4.1 解密 & 验签 RequestBodyAdvice

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DecryptRequestAdvice implements RequestBodyAdvice {@Overridepublic boolean supports(MethodParameter methodParameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) {return methodParameter.hasMethodAnnotation(ApiSecurity.class)&& methodParameter.getMethodAnnotation(ApiSecurity.class).decryptRequest();}@Overridepublic Object handleEmptyBody(Object body, HttpInputMessage inputMessage,MethodParameter parameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) {return body;}@SneakyThrows@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage,MethodParameter parameter, Type targetType,Class<? extends HttpMessageConverter<?>> converterType) {String body = StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8);ApiSecurityParam param = JSON.parseObject(body, ApiSecurityParam.class);// 1. 防重放校验(timestamp、nonce)checkReplay(param);// 2. RSA 私钥解密 AES 密钥String aesKey = RSAUtil.decryptByPrivateKey(param.getKey(), RsaKeyHolder.PRIVATE_KEY);// 3. AES 解密业务 JSONString json = AESUtil.decrypt(param.getData(), aesKey);// 4. 验签boolean ok = RSAUtil.verify(json + param.getTimestamp() + param.getNonce(),RsaKeyHolder.PUBLIC_KEY, param.getSign());if (!ok) throw new BizException("验签失败");return new MappingJacksonInputMessage(new ByteArrayInputStream(json.getBytes()),inputMessage.getHeaders());}
}

4.2 加密 & 加签 ResponseBodyAdvice

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType,Class<? extends HttpMessageConverter<?>> converterType) {ApiSecurity anno = returnType.getMethodAnnotation(ApiSecurity.class);return anno != null && anno.encryptResponse();}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType,MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {String json = JSON.toJSONString(body);// 1. 随机 AES 密钥String aesKey = AESUtil.randomKey(128);// 2. AES 加密响应String data = AESUtil.encrypt(json, aesKey);// 3. RSA 公钥加密 AES 密钥String encKey = RSAUtil.encryptByPublicKey(aesKey, RsaKeyHolder.PUBLIC_KEY);// 4. 生成签名String sign = RSAUtil.sign(json, RsaKeyHolder.PRIVATE_KEY);ApiSecurityParam resp = new ApiSecurityParam();resp.setKey(encKey);resp.setData(data);resp.setSign(sign);resp.setTimestamp(String.valueOf(System.currentTimeMillis()));return resp;}
}

五、工具类速览

  • RSAUtilencrypt/decrypt + sign/verify
  • AESUtilencrypt/decrypt 支持 PKCS5Padding
  • RsaKeyHolder:从 application.yml 或 KMS 读取公私钥

六、性能 & 安全小贴士

建议
对称加密AES-128-CBC/PKCS5Padding
非对称RSA-2048
防重放timestamp ±5 min + nonce 一次性
密钥轮换每日定时任务刷新 RSA 密钥对
性能AES 每次随机 IV,RSA 只加密 128bit 密钥,无压力

七、小结

通过以上 一个注解 + 两个 Advice,在 Spring Boot 中实现 企业级安全传输

  • 0 侵入:老接口贴注解即可
  • 高可扩展:支持 GET/POST、Header 传参、自定义算法
  • 已落地:可直接封装为 spring-boot-starter-security-api,全公司复用。

源码示例已上传 GitHub:
https://github.com/your-org/spring-boot-api-security-starter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915428.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《计算机网络》实验报告二 IP协议分析

目 录 1、实验目的 2、实验环境 3、实验内容 3.1 tcpdump 基本用法 3.2 wireshark基本用法 3.3 利用tcpdump抓包&#xff0c;wireshark分析包 4、实验结果与分析 4.1 tcpdump命令的基本用法 4.2 wireshark的基本用法 4.3 利用tcpdump抓包&#xff0c;wireshark分析包…

k8s学习记录(三):Pod基础-Node选择

一、前言 在上一篇文章中我们学习了Pod的一些基本的知识&#xff0c;今天我们将继续学习Pod。 二、K8S如何选择节点来运行Pod 我们知道在一个K8S集群中&#xff0c;会有多个工作节点&#xff08;Worker Node&#xff09;&#xff0c;那么k8s会选择那个node呢&#xff1f;接下…

3天功能开发→3小时:通义灵码2.0+DEEPSEEK实测报告,单元测试生成准确率92%的秘密

活动链接&#xff1a;https://developer.aliyun.com/topic/lingma-aideveloper?spma2c6h.29979852.J_9593490300.2.49b8110eeymlF8 前言 随着人工智能技术的迅猛发展&#xff0c;AI 赋能编程成为了必然趋势。通义灵码应运而生&#xff0c;它是阿里巴巴集团在人工智能与编程领…

【小沐学GIS】基于Rust绘制三维数字地球Earth(Rust、OpenGL、GIS)

&#x1f37a;三维数字地球GIS系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GI…

ARM 学习笔记(三)

参考文献&#xff1a;《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》1、内存类型 ARMv7-A 处理器中&#xff0c;将 Memory 定义为几种类型&#xff08;Memory Type&#xff09;&#xff1a; Strong…

Flask 框架(一):核心特性与基础配置

目录 一、为什么选择 Flask&#xff1f; 二、Flask 核心概念与初始化 2.1 程序实例初始化 2.2 运行配置&#xff1a;app.run () 参数详解 2.3 应用配置&#xff1a;三种参数设置方式 1. 字典直接配置&#xff08;简单临时场景&#xff09; 2. 配置文件导入&#xff08;生…

社交圈子系统开源社交源码 / 小程序+H5+APP 多端互通的底层技术分析

伴随社交产品向“圈子化”、“内容驱动”发展方向演进&#xff0c;打造一套支持小程序、H5、APP 互通的社交圈子系统&#xff0c;已经成为构建垂直社区的基础架构能力要求。本文围绕一套典型的多端社交兴趣平台&#xff08;即友猫社区平台&#xff09;的设计实践&#xff0c;对…

gitlab-runner配置问题记录

引言 笔者曾通过2种方式部署过 gitlab-runner&#xff0c;在 gitlab 中使用这个 runner 拉起 ci job 的过程中或多或少遇到些问题&#xff0c;主要都是 job 中无法访问宿主机的docker 等组件。本篇文档主要记录 gitlab-runner 安装及相关配置。 二进制部署 gitlab-runner 部署 …

每日面试题10:令牌桶

令牌桶算法&#xff1a;优雅的流量控制艺术在现代分布式系统中&#xff0c;流量控制如同交通信号灯般重要——它既不能让请求"堵死"系统&#xff0c;也不能放任流量"横冲直撞"。令牌桶算法&#xff08;Token Bucket Algorithm&#xff09;正是这样一种精妙…

【java】消息推送

文章目录Java网页消息推送解决方案 短轮询、长轮询、SSE、Websocket

STM32 | 有源蜂鸣器响,无源蜂鸣器播音乐

目录 Overview 有源蜂鸣器 无源蜂鸣器 有源蜂鸣器控制 GPIO配置 控制程序 无源蜂鸣器控制 反转GPIO控制 GPIO配置 控制接口 PWM控制 GPIO配置 控制函数 改变频率播音乐 原理 1. 频率决定音调 2. 占空比决定音量 GPIO初始化 结构体定义和音符频率表 播放接口 …

第十四章 gin基础

文章目录Gin快速搭建一个web服务Gin数据交互JSON串内容规范Gin使用结构体返回数据给前端Gin配置POST类型的路由Gin获取GET请求参数Gin获取POST请求参数-form-data类型Gin获取POST请求参数-JSON类型Gin获取参数绑定至结构体Gin快速搭建一个web服务 下载包 \\新建一个文件&…

Baumer工业相机堡盟工业相机如何通过YoloV8的深度学习模型实现PCB的缺陷检测(C#代码,UI界面版)

Baumer工业相机堡盟工业相机如何通过YoloV8的深度学习模型实现PCB的缺陷检测&#xff08;C#代码&#xff0c;UI界面版&#xff09;工业相机使用YoloV8模型实现PCB的缺陷检测工业相机实现YoloV8模型实现PCB的缺陷检测的技术背景在相机SDK中获取图像转换图像的代码分析工业相机图…

【Vivado那些事儿】AMD-XILINX 7系列比特流加密

前提&#xff1a;加密有风险&#xff0c;操作需谨慎前言在许多项目中&#xff0c;经过漫长的等待&#xff0c;我们的 FPGA 设计终于可以投入现场部署了。前期的资金的投入及知识产权的保护&#xff0c;我们需要对现场部署的 FPGA 进行比特流保护以防止逆向工程和未经授权的重复…

RK3588 安卓adb操作

adb&#xff08;Android Debug Bridge&#xff09;是一个用于与安卓设备进行通信和控制的工具。adb可以通过USB或无线网络连接安卓设备&#xff0c;执行各种命令&#xff0c;如安装和卸载应用&#xff0c;传输文件&#xff0c;查看日志&#xff0c;运行shell命令等。adb是安卓开…

【华为机试】70. 爬楼梯

文章目录70. 爬楼梯描述示例 1示例 2提示解题思路核心分析问题建模算法实现方法1&#xff1a;动态规划&#xff08;标准解法&#xff09;方法2&#xff1a;空间优化动态规划&#xff08;最优解&#xff09;方法3&#xff1a;递归 记忆化方法4&#xff1a;数学公式&#xff08;…

山东大学软件学院面向对象期末复习

面向对象 文章目录面向对象04 类封装接口 抽象类05 消息&#xff0c;实例化&#xff0c;静态变量方法消息动/静态类型语言对象创建类及实例具有下面特征对象数组的创建静态数据成员构造函数06_0 继承继承是向下传递的JAVA为什么不支持多重继承继承的形式特殊化继承替换原则规范…

让 Windows 用上 macOS 的系统下载与保姆级使用教程

模拟苹果桌面软件下载&#xff1a;https://xpan.com.cn/s/8NFAGT 还记得 Windows 11刚发布时&#xff0c;很多人就说“果里果气"的&#xff0c;但界面确实做的漂亮。 不知道现在有多少小伙伴正用着macOS&#xff0c;不过我敢确定&#xff0c;喜欢macOS的人绝对不少&#…

嵌入式硬件篇---继电器

继电器是一种通过小电流控制大电流的电磁开关&#xff0c;广泛应用于自动化控制、电力系统和电子设备中。以下从工作原理、应用场景和电路特点三个方面详细介绍&#xff1a;一、工作原理继电器本质是电磁控制的机械式开关&#xff0c;核心部件包括&#xff1a;线圈&#xff08;…

鸿蒙网络编程系列58-仓颉版TLS数字证书查看及验签示例

1. TLS数字证书验签简介 数字证书的签名验证是网络编程中一个重要的功能&#xff0c;它保证了数字证书是由可信任的签发方签署的&#xff0c;在此基础上&#xff0c;我们才可以信任该证书&#xff0c;进而信任基于该证书建立的安全通道&#xff0c;所以说&#xff0c;数字证书…