前言
在数据安全日益重要的今天,仅靠HTTPS就够了吗?对于敏感业务接口,我们往往需要额外一层的应用级加密。今天,就和大家深入聊聊接口加密的核心思路与SpringBoot一站式实现方案。
一、接口为什么要加密
接口加密的核心目的,用四个字概括就是:保护数据。具体体现在:
- 防泄漏:防止敏感数据(如用户身份、交易信息)在传输过程中被截获。
- 防篡改:确保接收到的数据就是发送方发出的原始数据,未被中间人修改。
- 防重放:防止攻击者截获合法请求后,重复发送进行恶意操作。
- 抗伪装:为客户端与服务端的双向身份验证提供基础。
当然不是说接口加密后,就能完完全全的保护我们的数据,但至少能防一部分人拿到我们的数据。而且接口加密在提升数据安全性的同时,也让系统的安全层级更上一层。而且接口加密感觉逼格是不是高过一点!!!
二、加密思路
1、加密简介
加密算法有很多,在能加密又能解密的算法可分为:
非对称加密算法,常见:
RSA、DSA、SM2、ECC- 非对称加密:加密和解密用 一对不同但配对的密钥(公钥 + 私钥),两者是 “唯一绑定” 的
- 特点:算法复杂,加解密速度慢,但安全性高。
- 一般与对称加密结合使用(对称加密对内容加密,非对称对对称所使用的密钥加密)
对称加密算法,常见:
AES、DES、3DES、SM4、Blowfish- 对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法。
- 特点:加密解密效率高,速度快,适合进行大数据量的加解密
单独用都有短板,混合使用才能扬长避短,我们选用混合加密:RSA+AES
混合加密思路:用AES加密业务数据(速度快),用RSA加密AES的密钥(安全性高),既保证效率又解决密钥传输问题。
2、加密流程
思路: 假设现在客户端是A,服务端是B,现在A要去B请求接口
第一步:密钥交换
- A生成RSA公私钥对,B也生成RSA公私钥对
- A和B互换公钥(公钥公开,私钥自己保存)
第二步:数据传输
- 客户端随机生成一个
AES密钥。 - 客户端用服务端的
RSA公钥加密这个AES密钥,并放在请求头(如key字段)中。 - 客户端用
AES密钥加密业务报文,放在请求体。 - 服务端收到请求后,用自己的
RSA私钥解开头部的key,得到AES密钥。 - 服务端用
AES密钥解密请求体,得到明文数据,处理业务。 - 服务端返回响应时,用客户端的
RSA公钥加密一个新的随机AES密钥,并用来加密响应体,流程同理。
这样做,既利用了非对称加密的安全性来完成最关键的密钥交换,又享受了对称加密处理业务数据时的高性能。
三、SpringBoot代码实现
灵魂拷问:如何在不改动既有业务代码的前提下,为接口统一加上加解密能力?
答案是:
- 方案一:**使用
@ControllerAdvice配合RequestBodyAdvice和ResponseBodyAdvice**。这相当于在请求进入Controller之前和离开Controller之后,安插了两个“关卡”,进行自动化的解密/加密。 - 方案二:使用AOP通过 “环绕通知” 拦截目标接口,在接口执行前解密请求参数,接口执行后加密返回值,全程不侵入业务代码。
用什么方案都行,如果没有特殊要求,其实用方案一更方便,因为它和SpringMVC 生命周期深度融合,兼容性更好。下面我们以方案一为例展开实现过程。
1、项目依赖准备
1 | <!-- 用于加密处理 --> |
- encryption-tools 是自己搞的demo,可以用其他的第三方工具加密如:
hutool也行
2、核心配置:密钥管理
1 |
|
配置文件application.yml中添加密钥配置:
1 | api: |
3、自定义注解:控制接口是否加密
不是所有接口都需要加密(比如公开的查询接口),用注解标记需要加密的接口:
1 | /** |
4、 请求解密:RequestBodyAdvice实现
EncryptRequestAdvice类:在请求到达Controller前,自动解密前端传的加密数据,业务代码拿到的是原始数据。
1 | /** |
解密工具类:DecodeInputMessage
具体的解密逻辑封装在这里,负责从请求头拿加密的AES密钥,解密后得到原始业务数据:
1 | public class DecodeInputMessage implements HttpInputMessage { |
5、 响应加密:ResponseBodyAdvice实现
EncryptResponseAdvice类:对Controller的返回值自动加密,前端拿到的是加密后的数据:
1 |
|
四、前端配套实现(Vue示例)
前端需要配合完成“加密请求→解密响应”的流程,核心依赖两个库:
jsencrypt:处理RSA加密(推荐增强版,支持长数据加密)CryptoJS:处理AES加密(Google开源,稳定可靠)
然后我使用的是Vue写的简单页面(业余前端)
1、核心代码实现
1 |
|
核心逻辑集中在testRequest()方法,完成“生成AES密钥→加密业务数据→加密AES密钥→发送请求→解密响应”的全流程,代码注释已清晰标注关键步骤。
2、注意点
- 后端需要注意的就是,controller参数需要用
@RequestBody包起来,如下:1
2
3
4
5
6@PostMapping("/test1")
@ResponseBody
public Object test1(@RequestBody(required = false) TestDto dto){
System.out.println("dto="+dto);
return Result.ok(dto);
} - 而前端传上来的时候
header需要设置"Content-Type": "application/json;charset=utf-8",确保请求体格式与后端解析方式一致。
3、最终效果
/test.png)
/postman.png)
在上面的postman中
data:里面的数据就是aes加密后的数据key:里面就是前端RSA公钥加密后的AES密钥(前端需要用私钥解密得到aes密钥,然后再用密钥解开data里面的数据)status:这个是状态码,如果报错了就不是200,不然报错了返回的数据,前端解几百年都解不开。
五、最后
接口加密不仅是技术需求,更是对用户数据负责的体现。希望本文提供的核心思路与完整实现,能帮助你快速在项目中落地应用级加密,筑牢数据安全的第一道防线。
扩展价值
本文方案具备良好的可扩展性,可根据业务需求快速迭代:
- 国密算法替换:将RSA替换为SM2、AES替换为SM4,满足金融、政务等领域的国产化合规要求。
- 分布式场景适配:密钥配置存入分布式配置中心,确保集群中所有节点密钥一致,支持水平扩展。
- 全链路加密:结合网关(如Spring Cloud Gateway)实现入口层统一加密,搭配服务间调用加密(如Dubbo接口加密),构建全链路数据安全体系。
源码地址
- 文中所有代码都已整理成可运行的Demo,包含SpringBoot后端、Vue前端、密钥生成工具,直接下载即可运行。
- 欢迎 Star ⭐ 和 Fork::
✨ 一个小小的邀请
如果这篇文章帮你理清了思路,不妨点个「赞&关注」。
期待在评论区,看到你的故事。 我们一起,把代码写得更明白。