时序侧信道攻击
基于时序侧信道的 Token 猜解攻击及修复方案
一、问题背景
在实际系统开发中,接口鉴权通常依赖于 Bearer Token 或 API Key。最常见的实现方式是将客户端传入的凭证与服务端保存的值进行字符串比较,例如:
if (expectedToken.equals(inputToken)) { // 鉴权通过}
这种写法在功能上没有问题,但在安全性上存在隐患。其根本原因在于:
字符串比较方法通常采用“逐字符比较 + 提前返回”的机制,这种实现方式可能引入时序侧信道攻击(Timing Side-Channel Attack)。
在一些对安全性要求较高的系统中,这 类 ** 问题属于典型的“隐蔽但严重”的漏洞。
二、字符串比较的执行机制
以 String.equals 为例,其底层逻辑大致如下:
从第一个字符开始逐位比较
一旦发现不相等,立即返回 false
如果全部字符相等,返回 true
例如:
expected = abcdefghinput = abxxxxxx
执行过程为:
第1位:a == a
第2位:b == b
第3位:c != x → 立即返回 false
也就是说,比较过程在第3位就结束了。
三、时序侧信道问题的产生
由于“提前返回”的存在,不同输入会导致不同的执行时间:
输入越接近真实值,比较时间越长
输入完全错误时,比较时间最短
这就导致:
比较耗时与“前缀匹配程度”相关
攻击者可以利用这一点,通过测量接口响应时间,逐步推断出正确的 Token。
四、攻击过程分析
假设服务端真实 Token 为:
SECRET123
攻击者可以通过如下方式逐步猜解:
第一步:确定第一位
攻击者构造请求:
Axxxxxxx → 响应时间短Sxxxxxxx → 响应时间较长
推断:
第一位是 S
第二步:确定第二位
SAxxxxxx → 时间短SExxxxxx → 时间较长
推断:
第二位是 E
重复上述过程
攻击者可以逐位枚举字符,通过时间差判断是否匹配,最终恢复完整 Token。
五、攻击成立的前提
这种攻击成立需要满足以下条件:
服务端使用“非恒定时间比较”
接口可被反复调用
响应时间差异可被测量
网络噪声相对可控(或通过统计方法消除)
在内网环境中,该风险相对较低,但对于以下场景需要特别注意:
对外开放的接口
统一接入层(多平台调用)
API 网关或鉴权中心
在你的平台架构中,统一接入层负责外部安全平台的数据接入与鉴权
因此该问题具有现实攻击面。
六、修复思路
- 使用摘要而不是明文比较
首先对 Token 进行哈希处理(如 SHA-256):
byte[] hash1 = sha256(expectedToken);byte[] hash2 = sha256(inputToken);
优势:
固定长度输出(256位)
避免直接暴露原始 Token
降低敏感数据泄露风险
- 使用恒定时间比较函数
关键点在于:
MessageDigest.isEqual(hash1, hash2);
该方法具备以下特性:
不会在中途提前返回
始终遍历完整数组
执行时间与数据内容无关
这类比较方式称为:
Constant- Time ** Comparison(恒定时间比较)
七、安全性对比
比较方式是否存在时序泄露原因String.equals存在提前返回Arrays.equals存在同样逐位提前退出MessageDigest.isEqual不存在全量比较
八、在实际系统中的意义
在网络安全平台中,鉴权失败不仅仅意味着访问被拒绝,还可能带来更严重的后果:
恶意伪造数据源
注入虚假漏洞或事件
干扰安全研判流程
污染标准事件数据层
尤其是在“统一接入层”这种系统边界位置:
所有外部数据的入口
所有安全事件的源头
一旦鉴权被绕过,后续所有模块(标准化、研判、通知、闭环)都会受到影响。
九、进一步增强建议
在实际工程中,可以在恒定时间比较的基础上进一步增强:
- 使用 HMAC
将 Token 改为:
HMAC(secret, message)
优点:
防止伪造
防止简单重放攻击
- 增加时间戳与随机数
token = HMAC(secret, timestamp + nonce)
可防止:
重放攻击
请求复用
- 配合限流与审计
接口限流(防暴力枚举)
日志记录(异常请求检测)
十、总结
字符串直接比较虽然简单,但在安全场景中存在潜在的时序侧信道风险。攻击者可以利用比较时间差异,逐步推断出认证凭证。
通过以下措施可以有效规避该问题:
对敏感凭证进行哈希处理
使用恒定时间比较函数(如 MessageDigest.isEqual)
结合 HMAC、时间戳等机制增强整体安全性
这一类问题的特点是:实现简单、风险隐蔽,但一旦被利用,影响范围广。因此在设计鉴权机制时,应尽量避免“隐式泄露信息”的实现方式。