BLE 继电器——威胁模型

了解固件源码但无法接触设备密钥的攻击者能做什么。

攻击面

固件是公开的,因此数据包格式、长度和算法(X25519、HMAC-SHA256、HKDF)都为人所知。BLE 走开放空口,广播和 GATT 写入都可被监听。 固件里和空口上都不存在任何密钥。

密钥存放在哪里:

攻击者做不到什么

AttackDefence
伪造 FIREHMAC-SHA256。没有 owner_secret 或 guest_key,这就是 2128 次暴力破解——不可行。
伪造 TIME 写入同样的 HMAC,覆盖 bleId + epochMs.
重放监听到的广播计数器单调递增;重复或回退时 HMAC 对不上。
重放监听到的 firenonce 环会作废用过的 nonce。
把控制器的时钟往回拨棘轮:任何 TIME < 棘轮值都会被拒绝。棘轮存于 NVS,断电也不丢失。
使用过期的捆绑包控制器运行过之后,棘轮至少等于最后一次真实时间。过期捆绑包的 validUntil 低于棘轮,fire 会因超期被拒。
把时钟拨快一年,把所有访客挡在门外每次访客 TIME 写入最多 +24 小时。主人不设上限——主人是可信的。
在第一位主人之上再配对成第二位主人配对后控制器把 owner_secret 存入 NVS,不恢复出厂设置就绝不再进入配对模式。

攻击者能做什么,代价如何

1. 把时间往前推——对合法访客的拒绝服务

Requires: 一份有效未过期的访客捆绑包。

Action: 每次进入范围就写入一个向前跳 24 小时的 TIME。

Limit: 每次会话 +24 小时;若上次同步不足一小时,还需要一次新的 fire。十次造访后棘轮就提前了十天,其他合法访客的令牌看起来就过期了。

另一面: 攻击者自己的令牌也按同一个伪造时间判定,因此提前失效。

怎么办: 主人过来写入真实时间。棘轮不会回退,所以不动,但新的访客令牌会带着当前的 validUntil 签发,此后对所有人都有效。恢复只需在服务器上刷新有效期。

Severity: 在主人到来之前的暂时性拒绝服务。不算严重。

2. 配对过程中的中间人

Requires: 在主人启动配对后的 90 秒窗口内,人身处控制器的射程之中。

Action: 在配对握手中替换成攻击者自己的 X25519 公钥。

Result: 控制器与攻击者而非主人完成配对。主人以为配对成功,却无法用手机打开任何东西。

当前防护: 只有时间窗口和主人的在场——主人看到配对未确认,会重来一次。

Hardening: 增加一个简单的验证码——控制器屏幕或串口上的四位数字——由主人在应用中确认。目前还没有这样的验证码。

Severity: 窗口很窄,既要靠近又要恰好落在那 90 秒内。实践中很难做到。

3. 物理恢复出厂设置

Requires: 能接触到控制器,并长按按钮。

Action: NVS 被擦除,owner_secret 被删除,控制器回到配对模式。

Result: 攻击者可把控制器配对到自己名下,主人失去访问权。

Defence: 把控制器装在受保护的位置——箱内、盖下。

Severity: 这跟把门口对讲机拆下来一样——不是密码学问题。

4. 通过 UART 或 JTAG 提取 owner_secret

Requires: 物理接触并转储闪存,且安全启动与闪存加密处于关闭状态——目前正是如此。

Action: 读取存有 owner_secret 的 NVS。

Result: 设备及全部访客令牌完全失守。

Defence: 启用 ESP32 的安全启动与闪存加密(efuse,不可逆)。目前未启用。

Severity: 家用可以接受。重要场所需要安全启动。

5. 占用 GATT 连接——拒绝服务

Requires: 处于 BLE 射程内。

Action: 连上就不断开。NimBLE 只支持有限数量的并发连接。

Result: 只要攻击者占着名额,合法客户端就连不上。

当前防护: 只有 NimBLE 自身的超时。

Hardening: 加一个空闲超时:客户端 5 秒内没有完成有效的 FIRE 就断开连接。

Severity: 攻击者在附近期间的暂时性拒绝服务。

6. 大量无效写入(连接伪装)

Action: 用垃圾写入轰炸控制器。

Result: 控制器将其丢弃并记入串口。其状态毫无变化,攻击者一走一切照旧。

哪些东西刻意不算防护

有三处看着像防护,其实不是。与其让人依赖它们,不如把话说明白。

广播中的状态字节 带一个 16 位标签。它只够抵御空口上的偶然损坏,仅此而已: 有心伪造者几秒就能把 16 位穷举一遍。该字节只驱动卡片上的“开/关”指示,不授予任何权限, 所以标签保持短小——每多一个字节,都要在每次唤醒时消耗电量。

“仅限应用”的密钥 依赖编译进 APK 的一个密钥。谁把文件解包,谁就拿到密钥并能伪造证明。 它只是抬高了随手用网页客户端的门槛,仅此而已。这类密钥真正的管控是把它绑定到某台设备的 指纹上——这项校验在服务器上执行,不依赖应用能否守住秘密。

访客密钥的有效期 在 BLE 上由控制器自己保证:令牌带有期限,控制器也有时钟。 其他类型的对象则根本没有期限——密钥一直有效,直到主人吊销。应用并没有说相反的话;但若 将来界面上也为这些类型加上时间限制,那就必须在服务器上执行,而不是画在卡片上。

小结

面向工业使用的标准加固:

  1. 安全启动与闪存加密(防 JTAG 与转储)。
  2. 在配对流程中加入验证码(防中间人)。
  3. 为 GATT 连接设置空闲超时(防占用)。
  4. 以恒定时间比较签名——固件与应用中均已完成:先前逐字节的比较会通过响应时间 泄露签名已被猜中多少字节。

对当下的使用场景这些都不算关键,但重要场所值得这样加固。