一、BLE 5.0+ 安全增强:不只是更快更远

BLE 5.0 发布的时候,很多人只盯着「2倍速度、4倍距离、8倍广播容量」这些亮眼参数。但我当时在项目里第一反应是——安全层面有没有跟上?

说实话,BLE 4.x 时代的安全模型已经暴露出不少问题。比如 LE Legacy Pairing 的 MITM 保护基本是摆设,只要攻击者能抢在配对前注入一个假密钥,整个链路就沦陷了。我曾在某 IoT 网关项目里亲眼见过这种攻击——攻击者用一块 20 块钱的 nRF52840 开发板,就能让智能门锁误以为自己在和合法手机配对。

1.1 LE Secure Connections:真正的端到端保护

BLE 5.0 强制要求支持 LE Secure Connections(当然,为了向后兼容,也保留了 Legacy 模式)。这个协议最大的变化是引入了 ECDH 密钥交换(椭圆曲线 Diffie-Hellman)。

你想想看,Legacy 配对用的是 TK(临时密钥),只有 6 位数字,暴力破解只需要 10^6 次尝试。而 Secure Connections 用的是 256 位 ECDH 密钥,破解难度完全不在一个量级。

核心变化一览:

  • Legacy:TK → STK → LTK(临时密钥推导链路,MITM 风险高)
  • Secure Connections:ECDH 公钥交换 → DHKey → LTK(数学上保证中间人无法推导)

我在做一款医疗手环时,客户要求必须通过 FDA 网络安全审查。当时我直接把 Legacy 配对禁掉了,只允许 Secure Connections。为什么?因为 FDA 审核员会逐行检查密钥生成逻辑——Legacy 的 TK 生成方式太容易被质疑。

1.2 数值比较 vs 密码输入:两种 MITM 防护

Secure Connections 提供了两种 MITM 防护方式:

方式 适用场景 我的经验
数值比较(Numeric Comparison) 双方都有显示屏 手机+手表场景最常用,用户确认数字是否一致
密码输入(Passkey Entry) 一方有输入能力 智能锁+手机场景,用户输入锁上显示的 6 位码

嗯,这里要注意:数值比较并不是「显示一个数字让你看一眼」那么简单。它背后是 确认值(Confirm Value) 的生成过程——双方各自计算一个哈希值,然后交换比较。如果中间人篡改了公钥,计算出的确认值必然不匹配。

我曾经踩过一个坑:某款国产芯片的 BLE 协议栈在数值比较时,没有正确实现「Nonce 随机数」的生成。结果每次配对生成的确认值都一样,攻击者可以重放。后来我帮他们提了 patch,核心问题就是随机数种子没初始化好。

二、BLE Mesh 安全:组网场景下的新挑战

BLE Mesh 是 2017 年 SIG 正式发布的规范。它和传统 BLE 点对点通信完全不同——Mesh 网络里一个节点可能要和几十个节点通信,密钥管理复杂度指数级上升。

2.1 三层密钥体系

Mesh 安全的核心是「分层隔离」。我习惯把它理解成三把锁:

  • 网络密钥(NetKey):保护整个 Mesh 网络的广播数据。所有节点共享同一个 NetKey。
  • 应用密钥(AppKey):保护特定应用的数据。比如灯控指令和门锁指令用不同的 AppKey。
  • 设备密钥(DevKey):每个节点独有,用于配置和 provisioning 过程。

我的建议: 在实际项目中,不要把 AppKey 设计成全局统一的。我曾经见过一个智能楼宇项目,所有灯控、窗帘、传感器都用同一个 AppKey。结果一个灯泡被破解,整栋楼的 Mesh 网络都能被控制。正确的做法是:按功能域划分 AppKey,比如「公共区域灯控」「办公室灯控」「会议室灯控」各用不同的密钥。

2.2 Provisioning 过程:入网即安全

Mesh 设备入网时,会经历一个 provisioning 流程。这个流程如果设计不好,就是最大的安全漏洞。

标准流程是这样的:

  1. Provisioner(配置设备)和未配网设备建立 OOB(带外)通道——可以是二维码扫描、NFC 触碰、PIN 码输入。
  2. 双方通过 ECDH 交换生成会话密钥。
  3. Provisioner 把 NetKey、AppKey、IV Index 等安全材料分发给设备。

我遇到过最离谱的情况是:某厂商为了「用户体验」,把 OOB 通道直接省略了,让用户手动输入一串 16 进制密钥。结果用户嫌麻烦,直接在论坛上贴出了密钥截图……嗯,安全设计不能指望用户自觉。

2.3 重放攻击与 IV Index

Mesh 网络里有个很巧妙的设计——IV Index(网络标识符索引)。它是个 32 位的计数器,每 192 小时递增一次。所有 Mesh 数据包都包含一个序列号(SEQ),接收方会检查 SEQ 是否递增。

为什么要这样?因为 Mesh 是广播网络,攻击者可以轻松抓包然后重放。如果没有 IV Index + SEQ 的双重校验,一个「开灯」指令可以被重放无数次。

注意: IV Index 更新时有个「过渡期」。如果网络里部分节点更新了 IV Index,部分还没更新,就会导致数据包被丢弃。我建议在固件里实现「IV Index 漂移检测」——如果连续收到多个来自不同 IV Index 的数据包,不要立即丢弃,而是缓存并等待网络同步。

三、蓝牙 SIG 安全规范:标准在演进

蓝牙 SIG 这些年一直在更新安全规范。我整理了几个关键版本的变化:

规范版本 安全增强 我的评价
Core 4.2 引入 LE Secure Connections(可选) 步子迈得不够大,Legacy 模式仍然保留
Core 5.0 强制 Secure Connections,废弃 Legacy 终于把 TK 淘汰了,但兼容性阵痛期很长
Core 5.1 增加 GATT 缓存安全机制 解决了「缓存中毒」攻击——攻击者伪造缓存数据让设备误以为已配对
Core 5.2 LE Audio 安全,加密广播 加密广播是个好东西,但实现复杂度高
Core 5.3 连接子速率安全优化 减少空口暴露时间,降低被嗅探概率

我个人觉得,5.1 的 GATT 缓存安全机制被很多人忽略了。攻击者可以利用缓存机制,让设备以为「这个手机之前配对过」,从而跳过配对流程。修复方式很简单——每次连接时重新验证绑定信息,不要完全信任缓存。

四、知识体系总览

下面这张图是我自己画的 BLE 安全协议扩展全景图。你可以把它当作本章的「地图」:

BLE 安全协议扩展全景图 BLE 5.0+ 安全增强 BLE Mesh 安全 蓝牙 SIG 安全规范 LE Secure Connections (ECDH) 数值比较 / 密码输入 废弃 Legacy 配对 三层密钥体系 Provisioning 入网安全 IV Index + SEQ 防重放 Core 4.2~5.3 演进 GATT 缓存安全 (5.1) 加密广播 (5.2) 核心原则:分层隔离 + 端到端加密 + 防重放 ECDH 密钥交换 | 三层密钥体系 | IV Index 同步 | 强制 Secure Connections

这张图把三个分支的关系理清楚了。你可能会问:为什么要把 BLE 5.0+ 和 Mesh 分开?因为 Mesh 虽然基于 BLE 5.0,但它的安全模型是独立设计的——Mesh 的 provisioning 流程、密钥分发、中继安全,都是传统 BLE 没有的。

五、实战避坑指南

最后分享几个我踩过的坑,希望能帮你省点时间:

坑1:Secure Connections 的兼容性陷阱

我曾经在项目里强制启用 Secure Connections,结果发现某款老手机(Android 8.0 以下)根本不支持。配对直接失败,用户反馈「连不上」。解决方案:在配对前先读取对端支持的 Feature 字段,如果不支持 Secure Connections,降级到 Legacy 并给出安全提示。

坑2:Mesh 的 IV Index 更新时机

Mesh 规范说 IV Index 每 192 小时更新一次。但如果你网络里有设备长时间离线,回来时 IV Index 已经变了,它发的包会被其他节点丢弃。我建议在设备端实现「IV Index 宽容窗口」——允许接收 IV Index 相差 1 以内的数据包,并触发同步流程。

坑3:加密广播的密钥管理

BLE 5.2 的加密广播(PAwR)需要广播者和扫描者共享一个密钥。如果密钥泄露,所有广播内容都能被解密。我见过最蠢的做法是把密钥硬编码在 App 里——反编译一下就拿到了。正确做法:通过 OOB 通道(比如扫码)分发密钥,并且支持定期轮换。

好了,这一章的内容就到这里。安全协议扩展是个持续演进的过程,SIG 几乎每年都在打补丁。我的建议是:不要等到规范稳定了再动手——先实现最核心的 ECDH + 分层密钥,后续的增强特性可以逐步迭代。


公众号:蓝海资料掘金营,微信deep3321