14、BLE数据安全:配对方式对比、加密传输与绑定存储

说到BLE的安全,我估计不少同学第一反应就是「配对弹窗」。嗯,确实,配对是用户能直接感知到的安全环节。但真正决定设备间通信是否安全的,是配对背后的加密机制、MITM保护策略,以及绑定信息的存储方式。

我在做智能门锁项目时,就踩过配对的坑。当时用户反馈说「手机靠近门锁就能开,太不安全了」。其实问题不在BLE协议本身,而是我们用了Just Works配对,没有任何MITM保护。说白了,谁在附近都能配对成功。后来改成Passkey Entry,用户才安心。

这一章,我就把BLE配对的三种方式、加密传输的MITM保护、以及绑定信息的存储,给你讲透。

14.1 配对方式对比:Just Works、Passkey Entry、Numeric Comparison

BLE的配对,本质上是两个设备协商一个临时密钥(TK),然后基于TK生成短期密钥(STK)或长期密钥(LTK)。不同的配对方式,区别就在于TK的生成方式——这直接决定了MITM攻击的防护能力。

配对方式 TK生成方式 MITM保护 用户交互 典型场景
Just Works TK = 0(固定值) 耳机、手环、传感器
Passkey Entry 一方显示6位数字,另一方输入 需要输入/确认 智能门锁、医疗设备
Numeric Comparison 双方显示6位数字,确认一致 需要确认 手机与手机、平板与配件

14.2 Just Works:简单但脆弱

Just Works,名字很直白——「就是能用」。它把TK固定为0,所以不需要用户做任何操作。配对过程自动完成。

但问题也出在这里。TK是0,意味着攻击者可以轻易计算出后续的加密密钥。我在项目中遇到过一种攻击场景:攻击者用嗅探设备抓取配对过程中的空中包,因为TK已知,直接就能解密所有通信。

⚠️ 注意:Just Works不提供MITM保护。如果你的设备涉及敏感数据传输(如支付、门禁、健康数据),千万不要用Just Works。它只适合那些「丢了也不心疼」的低成本设备。

14.3 Passkey Entry:输入6位数字

Passkey Entry的流程是这样的:一方(通常是显示器端)随机生成一个6位数字,另一方(通常是输入端)手动输入这个数字。双方用这个数字作为TK。

为什么它能防MITM?因为攻击者无法同时看到显示端和输入端的操作。他只能猜,但6位数字有100万种组合,猜中的概率极低。

我建议在智能门锁、保险柜这类设备上使用Passkey Entry。用户输入密码的过程,本身就是一种身份验证。不过要注意用户体验——如果每次连接都要输密码,用户会烦。所以通常只在首次配对时输入,后续通过绑定信息自动重连。

💡 小技巧:在Android端,你可以通过BluetoothDevice.createBond()触发配对。如果设备支持Passkey Entry,系统会自动弹出输入框。你不需要自己实现UI,系统会处理。

14.4 Numeric Comparison:双方确认数字

Numeric Comparison是三种方式中最安全的。它要求双方都显示一个6位数字,用户确认两边数字一致后,配对完成。

它的原理是:双方基于各自的公私钥对,通过椭圆曲线Diffie-Hellman(ECDH)算法计算出一个共享值,然后从这个共享值派生出6位数字。因为攻击者不知道私钥,所以无法伪造这个数字。

我在做手机与平板互传文件的功能时,用的就是Numeric Comparison。用户看到两边屏幕显示同样的数字,点一下「确认」,配对就完成了。既安全又直观。

🔐 核心要点:Numeric Comparison提供了最强的MITM保护。它适合双方都有显示屏的设备。如果只有一方有屏幕,那就只能用Passkey Entry了。

14.5 加密传输与MITM保护

配对完成后,BLE会进入加密阶段。加密使用的是AES-128-CCM算法,密钥来自配对时协商的LTK(长期密钥)或STK(短期密钥)。

但加密不等于安全。你想想看,如果配对阶段被MITM攻击了,攻击者拿到了密钥,那后续的加密通信对他来说就是透明的。所以MITM保护的关键,不在加密算法本身,而在配对阶段的密钥协商过程。

我曾经在测试中发现,有些厂商为了省事,在Passkey Entry中把TK固定为某个值(比如123456)。这跟Just Works有什么区别?攻击者只要试一次就知道了。所以一定要用随机生成的TK。

⚠️ 注意:MITM保护只覆盖配对阶段。配对完成后,如果设备被物理接触或系统被root,密钥可能被窃取。所以绑定信息的存储也很重要。

14.6 绑定信息存储

绑定(Bonding)是指配对完成后,双方保存对方的身份信息和密钥。下次连接时,可以直接使用这些信息恢复加密通道,不需要重新配对。

绑定信息通常包括:

  • LTK(长期密钥)
  • IRK(身份解析密钥)
  • CSRK(连接签名解析密钥)
  • 设备地址(Public Address或Random Address)

在Android端,绑定信息由系统蓝牙栈管理,存储在/data/misc/bluedroid/目录下。应用层无法直接访问这些文件。但如果你在做嵌入式设备,就需要自己设计存储方案。

我建议:

  • 使用安全芯片(如SE或TEE)存储密钥,不要明文存Flash
  • 如果必须存Flash,至少做一次加密存储
  • 绑定信息要绑定设备ID,防止重放攻击
💡 经验之谈:我在一个IoT项目中,把绑定信息直接存到了外部EEPROM里,结果被物理拆解后读出了密钥。后来改用MCU内置的加密存储区域,才解决这个问题。硬件安全边界一定要考虑进去。

14.7 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你可以看到配对方式、MITM保护、加密传输、绑定存储之间的关系。

BLE数据安全知识体系 配对方式 Just Works(TK=0) Passkey Entry(6位输入) Numeric Comparison(确认) MITM保护 Just Works:无保护 Passkey Entry:有保护 Numeric Comparison:强保护 加密传输 AES-128-CCM 绑定信息存储 LTK / IRK / CSRK 配对方式决定MITM保护强度 → 保护强度影响加密传输安全性 → 绑定信息需安全存储

14.8 总结

BLE数据安全,说白了就是三件事:

  • 选对配对方式——Just Works省事但不安全,Passkey Entry适合单屏设备,Numeric Comparison适合双屏设备
  • 重视MITM保护——加密算法本身没问题,但密钥协商过程才是薄弱环节
  • 安全存储绑定信息——密钥存不好,前面全白费

嗯,这一章的内容就到这里。你在实际项目中如果遇到配对相关的坑,欢迎来交流。


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