重放攻击是攻击者截获合法API请求后重复发送,导致重复扣款、重复下单等严重后果。由于请求本身是合法的,单纯靠加密无法防御。本文介绍多种防重放攻击的方案组合。
时间戳校验
最简单的防重放方案:请求中包含时间戳timestamp,服务端校验时间戳与当前时间之差是否在允许范围内(如5分钟)。超出范围的请求视为重放攻击拒绝。时间戳校验只能防止旧请求被重放,无法防止短时间内的快速重放。需要配合其他方案使用。客户端和服务端时间需要同步,使用NTP服务校准时间差异。
Nonce一次性随机数
Nonce是每次请求生成的唯一随机数,服务端记录已使用的Nonce,相同Nonce的请求拒绝。Nonce结合时间戳使用:过期时间戳的Nonce自动清理,减少存储压力。存储Nonce使用Redis设置自动过期,过期时间与时间戳容忍窗口一致。Nonce需要足够的熵值防止暴力碰撞。UUID或SecureRandom生成的随机数都可以作为Nonce。
签名机制
请求签名可以防篡改和防重放。签名流程:将所有请求参数按照字典序排序拼成字符串,拼接上timestamp和nonce,用客户端密钥进行HMAC-SHA256签名,签名结果放在请求头中。服务端用同样的算法和密钥计算签名,验证是否一致。签名验证同时完成了防篡改和防重放的功能。密钥通过前置分发或非对称加密交换。
Token绑定策略
防重放和Token绑定结合:每个Access Token关联一个递增序列号或随机值,每次请求使用序列号递增,服务端校验序列号是否递增。或者建立Token和请求的绑定关系,Token只能用于特定的请求、IP和设备。Token绑定增加了攻击者重放请求的难度。Token泄露后立即撤销,从源头解决重放攻击。综合使用多种方案可以构建强大的防重放能力。