蓝牙钥匙中继攻击原理与防护:从RTT测距到射频指纹的实战方案
发布时间:2026/10/2 1:01:15来源:尧图网络
蓝牙钥匙这几年普及得很快从汽车无钥匙进入、智能门锁到电动车、共享单车几乎成了智能硬件的标配。大家用惯了“走近自动解锁、走远自动上锁”的体验却很少去想一个事钥匙和锁之间那几十米的无线信号到底安不安全我自己做了一套基于 BLE 的蓝牙钥匙系统从硬件选型到协议调优都是自己一点点啃下来的中间最让人寝食难安的就是“中继攻击”。这个攻击不破解算法、不偷密钥也不做暴力破解纯粹靠“延长距离”就能把别人合法的钥匙信号搬到你的门前几秒钟打开锁走的时候现场还没有任何破坏痕迹。这篇文章我准备把中继攻击的原理、防护技术拆开揉碎讲一遍再把我自己在实际项目里用过的防护方案和踩坑记录分享出来。不管你是做嵌入式安全的、做智能锁产品方案的还是纯粹好奇自己家门锁安不安全的这篇内容应该都能给你一些参考。先说清楚中继攻击是个什么玩意儿。用一句话概括攻击者不需要知道你钥匙里的密钥也不需要破解任何加密算法只需要在真实钥匙和锁之间搭一座“桥”把钥匙的信号实时转发给锁锁就会以为钥匙就在身边然后开锁。因为信号是实时转发的钥匙端和锁端的所有认证流程、加密握手、动态码挑战都能正常完成从锁的角度看这就是一把货真价实、距离足够近的合法钥匙。1. 中继攻击原理拆解为什么你的钥匙会被“隔空搬运”1.1 BLE 蓝牙钥匙的工作流程要理解中继攻击得先明白蓝牙钥匙的正常通信流程。以我最常用的 BLE 方案为例整个解锁过程大致是这样的智能门锁或车载蓝牙模块处于广播状态周期性地向外发送广播包。蓝牙钥匙手机 App 或者实体蓝牙钥匙进入信号覆盖范围扫描到广播包后发起连接请求。连接建立后锁端生成一个随机挑战值Challenge下发给钥匙端。钥匙端用预共享的密钥对 Challenge 做签名或加密计算把响应Response回传给锁端。锁端验证 Response 的合法性再结合当前信号强度RSSI判断钥匙是否足够近满足条件后执行开锁操作。这套流程本身的加密和认证逻辑并没有大问题问题出在“距离判断”这个环节。锁端判断距离靠的是 RSSI 值而 RSSI 是一个可以被电磁环境、遮挡物、设备天线方向影响的物理量更关键的是这个数值只反映了“信号衰减到多少”根本证明不了“信号源真的离我有多远”。中继攻击瞄上的就是这一步。1.2 攻击链两个人两台设备就能“搬运”信号中继攻击的基本模型是攻击者需要两个角色分工协作。一个角色叫“嗅探中继”拿着便携设备靠近真实钥匙比如站在车主旁边或者把设备藏在车主经常出没的电梯口、车库角落。另一个角色叫“发射中继”拿着另一台设备贴近目标锁具。具体过程是这样的嗅探中继靠近车主的合法钥匙建立信号连接或者监听钥匙发出的信号。嗅探中继把接收到的原始信号通过无线网络可能是 4G、Wi-Fi 或者另一条射频链路实时传输给发射中继。发射中继在锁具旁边把信号原样广播或注入进去。对锁来说它收到的信号就是合法的钥匙信号而且因为发射中继就贴在锁旁边RSSI 值显示信号极强距离判断直接通过。整个攻击过程是“实时”的所以锁端如果额外加了一层“动态验证码”或“时间戳验证”也会被当作正常交互自然通过因为这些验证信息本身就是由真实钥匙实时生成并转发过来的。1.3 为什么传统校验方案拦不住中继攻击很多产品经理或者刚入行的开发会下意识问一句我们把加密算法做得足够强、把密钥长度拉长不就能防住中继攻击了吗答案是——防不住。因为中继攻击不触碰底层密码学它只是“偷听并转播”就像一个人站在墙外听到墙内的人说了句暗号然后对着对讲机把暗号一字不差地传到另一头开门的人听到暗号是对的但实际说话的人远在 500 米外。这也解释了为什么中继攻击会让安全圈这么头疼它不是在挑战你的算法而是在挑战你的“信任模型”——默认“信号源等于钥匙”、“距离近等于可信”。算法再强也弥补不了信任模型里的距离盲区。1.4 “第48次”意味着什么反复被验证的现实风险我在标题里写“第48次”不是说我自己被攻击了48次而是这个攻击场景在各类公开测试、学术研究、黑产演练中屡屡得手。很多知名安全团队用一套不到两千元的设备组合就能在短时间内打开多个主流品牌的蓝牙智能锁和汽车无钥匙进入系统。48次只是我这些年断断续续整理相关案例时记录下的一个触目惊心的统计数字。这类攻击的可怕之处在于成本低、隐蔽性高、成功率极高且受害者几乎没有察觉。2. 防护技术全景解析从算法到行为建模的多层防线2.1 基于距离证明核心与难点是“时延”而非“强度”最直接的防护思路是抛弃“信号强度定距离”的老办法改用“信号飞行时间定距离”。这个思路在学术界被称为 Distance Bounding Protocol距离边界协议核心逻辑是光速是一个有限常数信号飞行需要时间。如果一把钥匙声称自己在 1 米内那信号从钥匙到锁的飞行时间应该只有约 3 纳秒。如果实际测得的单向或往返时延明显超出理论值那就有理由怀疑信号是经过中继绕了远路。真实系统中几乎不可能做到纳秒级时间同步所以工程上普遍使用往返时间Round-Trip Time, RTT来间接推算距离。锁端发送一个魔数给钥匙钥匙收到后原样返回或者做极轻量处理后返回锁端记录从发出到收到的时间差。这个时间差包含了信号在空中飞行的两段路程也包含了钥匙端硬件的处理时间。关键在于处理时间必须被严格约束——如果钥匙端能快速响应这个方案在理论上可以限制中继距离。但难点也很明显BLE 协议栈本身的中断调度延迟、蓝牙芯片的随机延迟、手机端 App 的响应时间都可能引入不确定性。所以“基于时延”的方案在专用硬件比如定制蓝牙钥匙硬件上表现尚可在手机 App 场景下容易产生较大的测量抖动。实际工程里我通常不会单独依赖单一测距方案而是把时延测距和 RSSI 阈值、行为特征三者联合起来做综合判断。2.2 信号指纹识别利用硬件差异识别“冒名设备”每个蓝牙芯片在生产时都会因为硬件工艺偏差导致射频信号在频偏、相位噪声、天线效率等方面存在细微差异。这些差异构成了设备唯一的“射频指纹”。正常情况下同一把合法钥匙发出的信号指纹应该是稳定的。中继攻击虽然能完整转播数据内容但无法复制发射机的模拟前端特性——或者说要复制相当困难因为模拟层面的随机偏差不是数字信号能够轻易模拟的。在防护实践里我实现了一套简化的信号特征提取机制锁具在钥匙首次配对时采集并保存钥匙设备的 I/Q 数据偏移、信道频偏、信号包络特征。每次解锁时锁端重新提取这些模拟特征与保存的指纹做相似度匹配。如果匹配度低于阈值即使所有密码学的认证都通过了也照样拒绝开锁并触发告警。这个方案有一个致命缺点射频指纹会随着温度、湿度、电池电量下降等因素产生漂移。冬天冷风一吹钥匙的频偏可能就和夏天匹配不上了。我在实际测试中吃过不少苦头后来采用的折中方案是“允许一定偏差范围 设置动态学习窗口”系统在连续多次合法解锁后自动微调指纹基线避免因为环境变化造成误杀。2.3 密钥协商更新与一次性会话阻止“重放”衍生攻击中继攻击虽然本身不是重放攻击但很多攻击者会在中继的基础上做一些变种。比如他们虽然无法破解密钥但可以录下一段合法的完整解开流程等车主离开后再把这段录制数据回放给锁。如果协议设计得不够健壮锁会以为车主回来了然后开门。防御重放攻击的通用做法是“动态挑战 单调递增计数器 密钥定期更新”。Lock 生成一个随机数这个随机数只在当前会话中有效用过后立即作废。与此同时锁和钥匙两端共同维护一个会话计数器收到的计数值必须严格大于上一次记录的计数值从协议层面保证“历史流量无法再次使用”。我在协议栈里额外做了一层“双向密钥漂移”——每次成功解锁后两端共享的密钥会基于本次会话的随机数做一次不可逆向的派生生成一把新的会话密钥。这意味着即使某次会话数据被完整录制下一次解锁时密钥已经变化录制数据变成一堆废码。2.4 行为决策层锁也可以有“怀疑”机制密码与信号之外还可以加一层“行为逻辑”来对抗中继攻击。我给它起的名字叫“锁端怀疑引擎”。它的核心思想很简单锁不仅要验证“钥匙对不对”还要验证“这次使用过程像不像正常车主在开门”。举个例子一个正常车主从靠近门锁到解锁通常会有 1 到 3 秒的持续信号存在信号强度会从弱变强或相对稳定。而中继攻击经常出现的情况是信号在瞬间出现强度极高且异常稳定然后就消失了。这不符合正常行为曲线。我设计的行为特征维度包括信号出现到解锁请求发出的时间间隔应该大于某个最小值通常 800ms 以上并且小于某个最大值比如 10 秒。解锁请求前 2 秒内的 RSSI 方差不能太小也不能太大。单日解锁次数、解锁时段、连续失败后的行为模式都会被纳入评分机制。如果触发疑点锁进入升级认证模式要求用户输入 PIN 码、使用手机 App 二次确认或者短时间禁止解锁。这套机制挡住了不少“自动化、脚本化”的攻击尝试攻击者要模拟正常行为曲线就必须增加等待时间、动态调整发射功率攻击耗时和难度都会显著上升。2.5 NFC 中继攻击的对照同样是“信号搬运”为什么更难防最近 NFC 中继攻击也成了一个热门话题很多读者会拿它和蓝牙中继做对比。NFC 的工作距离本来就只有几厘米中继攻击需要在贴近刷卡设备的“发射中继”和贴近卡片的“嗅探中继”之间建立一条实时传输链路。传统 NFC 刷卡我们默认“贴得足够近”就是可信的但这个假设同样会被中继攻击打破而且不少已有门禁系统和支付终端对 NFC 的传输时延要求比较高一旦实时链路存在几毫秒延迟就可能导致读卡超时。相比 BLENFC 中继有个明显特点信道带宽低、交互步数多对实时性更敏感。这意味着防护方面除了类似的时延检测还可以通过“交互时序异常检测”来识别中继路径中引入的额外延迟。如果你是用手机替代实体 NFC 卡的方案还可以在 App 里叠加生物识别或 LBS 位置围栏进一步增加攻击难度。3. 防护方案实践我的一套可落地的蓝牙钥匙防中继实现3.1 整体架构选择我在做系统架构时把防护方案分成了“不可信链路层”和“可信决策层”两个部分。链路层的任务是尽量压缩中继攻击可操作的空间主要包括测距、指纹、协议抗重放。决策层的任务是在链路层数据基础上通过综合评分决定是否开锁。这套分层方式和传统互联网安全里的“纵深防御”是同一个思路单点失效并不会导致整个系统崩溃。3.2 Session 结构定义整个系统里最关键的一个数据结构就是这个会话结构体。它承载了链路层采集到的所有原始数据也是决策层的输入。我贴一段实际的示例代码你可以参考这个字段定义去设计自己的会话管理struct UnlockSession { // 协议层认证信息 challenge: [u8; 16], response: [u8; 32], counter: u32, // 时延测距数据 rtt_measurements: Vecu32, // 单位为微秒 average_rtt_us: u32, // 射频信号特征 rssi_measurements: Veci16, // dBm rssi_variance: f32, rf_fingerprint: RfFingerprint, // 包含频偏、I/Q偏移等 // 行为特征 time_since_first_contact: u64, // 毫秒 unlock_attempt_count: u32, hour_of_day: u8, // 综合评分结果 security_score: u8, // 0-100 decision: Decision, // Allow / Deny / Challenge }每个字段都不是白设计的。比如rtt_measurements我会存最近 5 次测距结果而不是只存一个平均值因为要看抖动情况——中继链路往往比真实链路抖动更大。rssi_variance用于判断信号变化曲线是否正常正常开门时 RSSI 会有一个渐进变化过程而贴脸中转的信号往往是一条平线。3.3 核心测距模块从“硬件限制”到“实测经验”BLE 的往返测距有两种主流方式一种是把时间戳写在数据包里另一种是用硬件时间捕捉引脚记录精确收发时刻。第一种方式实现简单但精度很差因为 BLE 协议栈、操作系统调度、蓝牙芯片内部缓冲都会引入毫秒级的不确定性而毫秒级的不确定性对应的是数百公里的距离误差对防中继来说毫无意义。第二种方式我在芯片选型时专门挑了一颗支持 RF 时间捕捉功能的蓝牙 SoC它可以在射频前端检测到前导码的瞬间打上一个硬件时间戳最大程度避免了协议栈调度干扰。实测下来在室内环境往返测距时间可以从毫秒级降到微秒级抖动范围控制在几微秒到几十微秒。测距模块的实际逻辑是这样的锁端发一个预设的测距包钥匙端收到后立即原样返回。锁端记录发出时间 T1 和收到时间 T4从数据包里解析出钥匙收到时间 T2 和回复时间 T3则单程飞行时间大致等于Tflight ((T4 - T1) - (T3 - T2)) / 2其中 (T3 - T2) 是钥匙端的处理延迟需要从数据包字段中读出来。但如果钥匙端被攻击者控制这个字段可能就是伪造的。所以整个方案里我始终坚持一个原则硬件时间戳必须由密码学保护不能被任意的普通数据包伪造。这也是为什么定制硬件要比纯手机 App 方案安全得多的原因。3.4 综合评分决策给每一层防护设置权重单靠任何一个维度的数据都不足以做最终判断我的做法是把时延测距、RSSI 特征、射频指纹、行为特征四项分别打分再按加权系数合成一个最终安全评分。我自己调试下来比较合理的权重配比是RTT 测距结果权重最高40%射频指纹次之30%RSSI 特征15%行为特征15%。原因很简单RTT 是最难伪造的物理量中继链路每增加一米就必须多付出约 6.7 纳秒的纯信号飞行时间成本再加上中继设备的转发处理延迟这个放大效应非常明显。射频指纹的识别在小样本场景下容易漂移所以权重不宜过高。我也遇到过一种很刁钻的情况攻击者把发射中继和真实钥匙放在了同一物理空间里比如同一个房间、同一辆车上这种情况下往返测距的时间和真实钥匙几乎一样。应对方案是加做射频指纹判断和行为特征判断——即使中继转发了全部数字逻辑模拟前端始终是攻击者的硬件指纹必然和初始配对时采集到的合法钥匙特征不一致。3.5 一把锁的完整判定流程整个解锁流程我在代码里实现成了一个状态机核心判定逻辑可以用下面这段伪代码来概括function evaluate_unlock(session): if not verify_challenge_response(session): return DENY if session.counter last_counter[session.key_id]: return DENY score 0.0 // RTT 测距 rtt_score compute_rtt_score(session.average_rtt_us, session.rtt_measurements) score 0.4 * rtt_score // 射频指纹 fingerprint_score compute_fingerprint_score(session.rf_fingerprint) score 0.3 * fingerprint_score // RSSI 行为特征 rssi_score compute_rssi_behavior_score(session.rssi_measurements, session.rssi_variance) score 0.15 * rssi_score // 行为特征 behavior_score compute_behavior_score(session.time_since_first_contact, session.hour_of_day) score 0.15 * behavior_score if score 85: return ALLOW else if score 60: return CHALLENGE // 升级认证 else: return DENYCHALLENGE是我特别喜欢的一个状态——如果只是有可能可疑但不完全确定直接把门锁死了也不好此时让用户走一次二次认证比如在锁端输入 PIN 码。这样既不会把合法用户在恶劣环境中挡在门外又能让自动化中继攻击无路可走。3.6 参数配置参考一版实测可用的配置表下面这组参数是经过我上百次测试后确定的一套相对稳妥的默认配置适合室内智能门锁场景供你参考参数推荐值备注最大允许 RTT400 微秒对应约 60 米等效距离留足余量RTT 抖动容忍度平均值的 ±25%超过则该项评分直接减半RSSI 阈值-65 dBm 以上低于该值默认距离不可信RSSI 方差最小值0.5 dBm过小说明信号可能是被稳定放置的中继设备发射的指纹匹配阈值85%实测低于 80% 时可能是温度漂移85% 为平衡点连续失败封锁时间30 秒中继攻击者会因此大幅增加攻击耗时升级认证触发线安全评分 60-85触发 PIN 码二次验证测距次数每次请求测量 5 次取中位数有效过滤突发抖动干扰需要注意这套参数不是拿来就能直接用的不同芯片、不同天线设计、不同安装环境木门、铁门、玻璃门对信号特性影响很大。上了现场之后必须先采集一组基线数据再根据基线的均值和方差情况做调整。4. 常见问题与排查技巧实录4.1 低温环境下指纹匹配率骤降冬天室外环境我的测试设备出现过指纹匹配率从 90% 掉到 60% 以下的情况一开始还以为算法有 bug查了整整两天最后用频谱仪对比不同温度下的信号特征才发现温度对所使用晶振的频偏影响非常明显。解决思路是在指纹比对时加入温度补偿项——锁端增加一个温度传感器用不同温度区间训练一套对应的指纹基线。如果你不想做那么复杂最简单的方式是放宽指纹匹配阈值同时把行为特征和人工确认的权重提高牺牲一点自动通过率来保稳定性。4.2 金属门框导致 RTT 测距波动智能门锁装在金属防盗门上时金属会反射甚至屏蔽部分射频信号容易让多径效应变得更加严重。同一个位置的钥匙RTT 测量值能在一秒内上下跳动几十微秒如果不处理中继防护机制会把这种情况误判成“中继链路抖动”。排查方法是用频谱仪或者手机 App 先看门框附近的 RSSI 多径分布如果是金属环境就把测距次数加大到 8 到 10 次同时改用中位数而不是平均值作为最终判定量抗干扰能力会好很多。4.3 手机 App 作为钥匙的场景容易触发误报手机方案最容易遇到的问题就是 RTT 极不稳定。BLE 芯片收到数据包到应用层响应之间存在太多不可预期的延迟尤其是不同手机品牌、不同系统版本的蓝牙调度策略天差地别。我测试过一台低端安卓手机处理一个往返响应需要 1 到 2 毫秒折算成距离达到三百米以上。所以对于纯手机 App 钥匙我建议不要启用严格的 RTT 测距而是以 RSSI 渐变曲线 行为特征 用户 PIN 码作为主要防护手段。如果你实在想在手机方案里加入 RTT 辅助判断建议把最大允许阈值放宽到 2 毫秒而且只把它当作异常检测的辅助信号别当成唯一依据。4.4 多把钥匙同时使用时的指纹混淆家里通常不止一把钥匙几把钥匙放在同一张桌子上同时被锁端扫描到时信号会互相干扰指纹提取可能发生混淆。我的解决方案是在协议层面给每把钥匙分配独立的物理信道偏移或在时间上错开测距信号。每次建立的连接都严格绑定钥匙 ID指纹特征按 ID 单独入库绝不混合使用。4.5 中继攻击的告警日志长什么样为了验证中继攻击防护是否正常工作我在日志系统里加了专门的攻击特征标记。一个典型的被拦截日志看起来是这样的{ event: unlock_rejected, reason: rtt_anomaly, key_id: ble_key_07, average_rtt_us: 1280, expected_rtt_us: 250, rssi_dbm: -34, rssi_variance: 0.2, fingerprint_similarity: 0.92, security_score: 31, decision: deny }注意这里有个很微妙的地方RSSI 显示信号极强-34 dBm指纹相似度也高达 92%但 RTT 却是正常值的 5 倍。这就是典型的中继攻击特征——信号可以很强、指纹可以接近但多出来的时间和处理链路是藏不住的。看到这种日志组合基本可以判定是中继攻击。4.6 一条超级实用的测试方法最后分享一个我每次调完参数都要做的完整攻防测试流程。准备两台支持蓝牙抓包的设备其中一台连上钥匙另一台连上锁然后用一个脚本把从钥匙端抓到的原始数据包实时转发到锁端设备模拟完整的双向中继通路。这套设备搭建完你可以反复调整中继链路的长度、路由器延迟、发射功率观察锁端最终的表现。我的经验是只要中继路径上多出 10 米网线或者一个 Wi-Fi 路由器转发RTT 测距这一关大概率就能看出破绽而指纹识别则能抓住那些特意把中继设备紧贴钥匙的情况。我个人在这些测试里最大的体会是防中继攻击不能指望某一个“银弹”式算法越是底层的物理特征越可靠但越稳定可靠的特征往往越难在普通硬件上获取。真正耐打的产品一定是在芯片选型阶段就把安全能力考虑进去的而不是等固件写完再打补丁。安全设计越靠前成本越低效果越好。如果你正在设计新产品的安全方案我的建议是从 RTT 硬件时间戳和射频指纹采集这两个能力出发找芯片远比你后期在协议层死磕要省力得多。
网站建设高端定制企业官网