【Java】如何有效防止API的重放攻击?API接口防止参数篡改?

news2024/11/23 4:31:50

文章目录

  • 前言
  • 一、API接口常见的安全防护要做到主要有以下几点:
  • 二、请求参数防篡改
  • 三、防止重放攻击
    • 3.1、基于timestamp的方案
    • 3.2、基于nonce的方案
    • 3.2、基于timestamp和nonce的方案
    • 3.3、微信公众号如何保证消息不会被重放攻击

前言

API重放攻击(Replay Attacks)又称为重播攻击、回放攻击。它的原理就是把之前窃听到的数据原封不动的重新发送给接收方。HTTPS并不能防止这种攻击,虽然传输的数据都是经过加密的,窃听者无法得到数据的准确定义,但是可以从请求的接收方地址分析这些数据的作用。比如用户登录请求时攻击者虽然无法窃听密码,但是却可以截获加密后的口令然后将其重放,从而利用这种方式进行有效的攻击。

所谓重放攻击就是攻击者发送一个目的主机已经接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,重放攻击是计算机世界黑客常用的攻击方式之一。

一次HTTP请求,从请求方到接收方中间要经过很多路由器和交换机,攻击者可以在中途截获请求的数据。假设在一个网上存款系统中,一条消息表示用户支取了一笔存款,攻击者完全可以多次发送这条消息而偷窃存款。
重放是二次请求,如果API接口没有做到对应的安全防护,将可能造成很严重的后果。

一、API接口常见的安全防护要做到主要有以下几点:

  • 防止sql注入
  • 防止xss攻击
  • 防止请求参数被篡改
  • 防止重放攻击

主要防御措施可以归纳为两点:

  • 对请求的合法性进行校验
  • 对请求的数据进行校验

防止重放攻击必须要保证请求仅一次有效。需要通过在请求体重携带当前请求的唯一标识,并且进行签名防止被篡改。所以防止重放攻击需要建立在防止签名被篡改的基础之上。

二、请求参数防篡改

采用https协议可以将传输的明文进行加密,但是黑客仍然可以截获传输的数据包,进一步伪造请求进行重放攻击。如果黑客使用特殊手段让请求方设备使用了伪造的证书进行通信,那么https加密的内容也会被解密。
在API接口中我们除了使用https协议进行通信外,还需要有自己的一套加解密机制,对请求的参数进行保护,防止被篡改。

过程如下:

  • 客户端使用约定好的秘钥对传输的参数进行加密,得到签名值signature,并且将签名值也放入请求的参数中,发送请求给服务端
  • 服务端接收到客户端的请求,然后使用约定好的秘钥对请求的参数(除了signature以外)再次进行签名,得到签名值autograph。
  • 服务端比对signature和autograph的值,如果对比一致,认定为合法请求。如果对比不一致,说明参数被篡改,认定是合法请求。

因为黑客不知道签名的秘钥,所以即使截获到请求数据,对请求参数进行篡改,但是却无法对参数进行前面,无法得到修改后参数的签名值signature。
签名的秘钥我们可以使用很多方案,可以采用对称加密或者非对称加密

三、防止重放攻击

3.1、基于timestamp的方案

每次HTTP请求,都需要加上timestamp参数,然后把timestamp和其他参数一起进行数字签名。因为一次正常的HTTP请求,从发出到达服务器一般都不会超过60s,所以服务器收到HTTP请求之后,首先判断时间戳参数与当前时间比较,是否超过了60s,如果超过了则认为是非法请求。

一般情况下,黑客从抓包重放请求耗时远远超过了60s,所以此时请求中的timestamp参数已经失效了。

如果黑客修改timestamp参数为当前的时间戳,则signature参数对应的数字签名就会失效,因为黑客不知道签名秘钥,没有办法生成新的数字签名。

但是这种方式的漏洞也是显而易见,如果在60s之内进行重放攻击,那就没办法了,所以这种方式不能保证请求仅一次有效。

3.2、基于nonce的方案

nonce的意思是仅一次有效的随机字符串,要求每次请求时,该参数要保证不同,所以该参数一般与时间戳有关,我们这里为了方便起见,直接使用时间戳的16进制,实际使用客户加上客户端的ip地址,mac地址等信息做个哈希之后,作为nonce参数。

我们每次将请求的nonce参数存储到一个”集合“中,可以json格式存储到数据库或缓存。

每次处理HTTP请求时,首先判断该请求的nonce是否在该集合中,如果存在则认为是非法请求。

nonce参数在首次请求时,已经被存储到了服务器上的集合中,再次请求会被识别并拒绝。

nonce参数作为数组签名的一部分,是无法篡改的,因为黑客不清楚token,所以不能生成新的sign。

这种方式也有很大的问题,那就是存储nonce参数的集合会越来越大,验证nonce是否在集合中的耗时会越来越长。我们不能让nonce集合无限大,所以需要定期清理该集合,但是一旦该集合被清理,我们就无法验证被清理的nonce参数了。也就是说,假设该集合平均1天清理一次的话,我们抓取到的该url虽然当时无法进行重放攻击,但是我们还是可以每隔一天进行一次重复刚攻击的。而且存储24小时内,所有请求的nonce参数,也是一笔不小的开销。

3.2、基于timestamp和nonce的方案

nonce的一次性可以解决timestamp参数60s的问题,timestamp可以解决nonce参数集合越来越大的问题。防止重放攻击一般和防止请求参数被篡改一起做。请求的Headers数据如下图所示。
在这里插入图片描述

我们在timestamp方案的基础上,加上nonce参数,因为timestamp参数对于超过60s的请求,都认为是非法请求,所以我们只需要存储60s的nonce参数集合即可。
API接口验证流程:

String token = request.getHeader("token");
String timestamp = request.getHeader("timestamp");
String nonceStr = request.getHeader("nonceStr");

String url = request.getHeader("url");

String signature = request.getHeader("signature");


if(StringUtil.isBlank(token) || StringUtil.isBlank(timestamp) || StringUtil.isBlank(nonceStr) || StringUtil.isBlank(url)
|| StringUtil.isBlank(signature))
{
    return;
}

UserTokenInfo userTokenInfo = TokenUtil.getUserTokenInfo(token);

if(userTokenInfo == null){
    return;
}

if(!request.getRequestURI().equal(url)){
return;
}

if(DateUtil.getSecond()-DateUtil.toSecond(timestamp) > 60){
    return;
}

if(RedisUtils.haveNonceStr(userTokenInfo,nonceStr)){
    return;
}

String stringB = SignUtil.signature(token, timestamp, nonceStr, url, request);
if(!signature.equals(stringB)){
    return;
}
RedisUtils.saveNonceStr(userTokenInfo,nonceStr,60);

3.3、微信公众号如何保证消息不会被重放攻击

使用微信公众平台的接口需要在微信公众平台设置token。这里假设token是不会被攻击者知道的,相当于一个PSK(Pre Shared Key)微信发消息会有三个参数:signature、timestamp和nonce。
验证是否为微信发送的消息流程如下:

$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
// 按照$token,$timestamp,$nonce的顺序组成数组
$tmpArr = array($token, $timestamp, $nonce);
// 按照字典序排序
sort($tmpArr, SORT_STRING);
// 将排序后的数组串成字符串
$tmpStr = implode( $tmpArr );
// 用sha1计算签名
$tmpStr = sha1( $tmpStr );
// 校验签名
if( $tmpStr == $signature ){
    return true;
}else{
    return false;
}

这里在使用的时候,这里针对消息的重放攻击的防护应该检查nonce值是否已经存在,如果已经存在可能为非法通知,按道理来讲也应该检查这里timestamp和当前时间比较是否已经过了一定的时间,但是这里在微信公众号开发文档中并没有说明,这里其实应该是需要验证消息是否是否在同一个时间戳内的,如果接收到的消息距离发送的时间已经超过1s就可以直接丢弃了,当然在网络不好的情况下会造成丢消息。

另外一个这里针对重试或者幂等性的要求上要做到解密后消息中去,比如发起重试使用同样的消息id即可。虽然每次的nonce值是不一样的,但是消息的id是一样的,就可以区分出来是否为同一个消息的重试发送。

这里一般的做法是抽出一个前置网关,做消息的解密和加密,后端服务进行消息的处理,消息的处理上对重试带来的幂等性问题做处理就可以了。

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

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

相关文章

uniapp调接口出现跨域问题。

今天在写uniapp项目的时候,使用在线模拟接口的时候,出现跨域问题。 【问题描述】: ①在内嵌浏览器运行,不会出现跨域问题,好像是内嵌浏览器自动去掉了跨域问题。 ②在外部浏览器调用的时候会出现跨域问题。&#xf…

Yalmip工具箱使用教程(2)-决策变量进阶

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译:https://yalmip.github.io/tutorials/ 1.决策变量的定义 1.1 sdpvar 上文简单介绍了sdpvar函数的用法,接下来将对其进行详细介绍。复习一下,sdpvar函数的基本语…

常用化合物谱图数据库查询系统-40个软件免费查!

化学图谱是用于描述化学物质结构和性质的图形化表示方法,在有机化学、材料科学、生物化学、药物化学等领域都被广泛的应用研究分析。不同类型的化学谱图适用于不同的化学分析和研究领域,为此笔者调研了常用化合物谱图数据库及各个类型的主流使用化学谱图…

(RX200)R5F52315ADFP/R5F52318ADFL/R5F52316CDFL微控制器基于RXv2 32位内核,54MHz 闪存 LQFP

RX200 32位微控制器 (MCU) 在功率效率和性能之间实现了平衡。这些MCU在工作模式下的电流消耗为0.12mA/MHz,在待机模式下的电流消耗仅为0.8μA(保留RAM内容)。RX200 MCU具有54MHz的最高CPU运行速度,可提供4.16 CoreMark/MHz的高性能…

Home Assistant 南方电网 计算电费

目录 1.China Southern Power Grid Statistics集成2.获取当月用电情况3.计算电费然后在UI上显示3.效果 1.China Southern Power Grid Statistics集成 链接 2.获取当月用电情况 因为我的电费是固定的,没有阶梯电价 用电量 * 0.63906875 电费 3.计算电费然后在UI…

ESXI8.0安装教程,在VMware Workstation安装esxi

文章目录 🐟前言🐟安装🐟在VMware WorkStation中创建虚拟机🐟ESXI部署安装🐟安装完成后配置 🐟前言 ESXI8.0版本开始最低RAM从以前的4GB变为8GB 本文所使用到的镜像以及Key都可以到我的网站中下载 地址&…

Python——— 面向对象

(一)初识面向对象 Python完全采用了面向对象的思想,是真正面向对象的编程语言, 完全支持面向对象的基本功能,例如:继承、多态、封装等。 Python 支持面向过程、面向对象、函数式编程等多种编程范 式。 Pyth…

数据结构初阶--排序2

目录 前言快速排序思路hoare版本代码实现挖坑法代码实现前后指针法代码实现 快排优化三项取中法代码实现三指针代码实现 快排非递归代码实现 归并排序思路代码实现归并非递归代码实现 计数排序思路代码实现 前言 本篇文章将继续介绍快排,归并等排序算法以及其变式。…

2023年iOS App Store上架流程详解(上)

目录 1.注册开发者账号 2.登录并配置人员 3.申请证书和配置文件 一.证书管理​ 二.新建证书​ 三.使用appuploader服务同步证书​ 1)申请证书 2)添加Identifiers和配置App ID 3)申请配置文件 1.在Xcode项目中配置签名 2.上传应用包…

数据库应用:死锁、悲观锁、乐观锁

目录 一、理论 1.死锁 2.悲观锁 3.乐观锁 二、总结 一、理论 1.死锁 (1)概念 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系…

INVDIA GPU参数列表:P100,V100,A100,A800,H100等性能参数

一、P100与V100 训练深层神经网络的时候,V100比P100快大约2倍 二、A100 三、A800 四、H100 引用 1、 世上最全NVDIA GPU参数列表: V100, A100, A800,H100,3090,4090, A40&#xf…

Unity使用Android Stdio接入SDK制作AAR包

最近需要在Unity2021版本中接入SDK,发现和直接接入SDK有些区别,这里把接入的流程记录一下。 Unity在最新的版本中把UnityPlayActivity.java,从Class.jar中移除,需要在Unity的工程内找到这个文件,并把其加入到Android …

【监控系统】Prometheus监控组件Mysql-Exporter配置实战

Mysql-Exporter主要监控Mysql数据库的稳定性、吞吐量、连接情况、缓冲池使用情况、查询性能等各项指标,是我们压测时常常需要监控的一些指标。 目前,Exporter 支持高于5.6版本的 MySQL 和高于10.1版本的 MariaDB。在 MySQL/MariaDB 低于5.6版本时&#…

MobPush 最佳实践:消息重弹

功能概述 消息重弹功能,可在安卓在线通道送达的消息被其他消息挤下去时,重新置顶,增加消息的曝光度和点击率。 适用场景 仅支持Mob通过自有TCP通道下发的通知消息,不支持自定义推送消息支持开发者后台和推送API配置使用 功能使…

安天逆向教程——常用汇编语句

一.汇编基础 二.条件分支 反汇编时更多关注这些条件分支。如果看懂这些条件分支,会对程序的大体逻辑有一个整体的了解。 至于程序里面的细节,有时会省略掉。往往关键的跳转理解了甚至进行一点点的改动,就会使得程序发生翻天覆地的变化。 三…

读书笔记怎么写?《金字塔原理》读书笔记

​生活工作中有很多需要表达的场景,表达最重要的是逻辑清晰,表达出来的想法才能被理解,进而解决生活或工作中的困境。 《金字塔原理》详细地介绍了思维表达的方法,金字塔原理除了能够帮助人们以书面形式组织和表达思想以外&#x…

Vue3 组件之间父子通信

文章目录 Vue3 组件之间父子通信概述选项式API父传子子传父 组合式API父传子子传父 Vue3 组件之间父子通信 概述 所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。 选项式…

虚拟现实:将数字融入现实

随着科技的不断进步,虚拟现实正逐渐走进我们的现实生活,为我们带来了许多新的体验和可能性。虚拟现实技术将数字世界与真实世界融合在一起,为我们创造了令人惊叹的沉浸式体验。让我们一起探索虚拟现实正在走进现实的意义和影响。 虚拟现实为我…

C语言进阶之通讯录的实现(静态版和动态版)以及动态内存管理

通讯录的实现及动态内存管理 1.通讯录实现要求2.静态版通讯录实现2.1 contact.h文件实现2.2 contact.c文件实现2.3 main.c文件实现2.4 静态版通讯录全部文件代码 3.动态内存管理3.1 为什么存在动态内存分配3.2 动态内存函数的介绍3.3 常见的动态内存错误3.4 C/C程序的内存开辟3…

海盗搜身-2022年全国青少年信息素养大赛Python国赛第9题

[导读]:超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲,这是超平老师解读Python编程挑战赛真题系列的第11讲。 全国青少年信息素养大赛(原全国青少年电子信息智能创新大赛)是“世界机器人大会青少年机器人设…