13、BLE数据加密漏洞:CCM模式安全分析、加密初始化向量重用、数据包完整性校验绕过、加密降级攻击
BLE的加密机制,说白了就是一套“锁门系统”。门锁得再好,钥匙管理不当也是白搭。今天我们来聊聊这套系统里最容易出问题的几个环节。
我个人习惯把BLE加密比作一个保险箱。CCM模式是保险箱的锁芯,初始化向量是钥匙的齿形,完整性校验是保险箱的报警器,而加密降级攻击就是骗子假装自己是管理员让你换把破锁。每个环节都有坑,我一个个说。
CCM模式:看似完美,实则暗藏玄机
CCM(Counter with CBC-MAC)是BLE加密的核心。它把CTR模式的加密和CBC-MAC的认证合二为一。听起来很完美对吧?但我在项目中遇到过一个问题——CCM对nonce(临时数)的依赖极其敏感。
CCM的工作流程大致是这样的:
加密过程:
1. 生成nonce(8字节)+ 计数器(4字节)
2. 用AES加密nonce || counter,得到密钥流
3. 明文 XOR 密钥流 = 密文
4. 同时计算CBC-MAC,生成MIC(4字节或8字节)
解密过程:
1. 用同样的nonce + counter生成密钥流
2. 密文 XOR 密钥流 = 明文
3. 验证MIC是否匹配
这里有个关键点:nonce绝对不能重复使用。一旦重复,攻击者就能通过两次密文的XOR直接得到明文的XOR结果。嗯,这可不是危言耸听。
核心问题:CCM的安全性完全建立在nonce的唯一性上。如果nonce重用,加密就形同虚设。
加密初始化向量重用:最致命的低级错误
初始化向量(IV)在BLE里其实就是nonce的一部分。BLE 4.2及以后的版本中,IV是每次加密会话随机生成的。但问题出在实现上。
我曾经逆向过一个智能门锁的固件,发现它的IV生成逻辑是这样的:
// 错误示例:IV生成逻辑
uint8_t iv[8];
memcpy(iv, (uint8_t*)&sys_tick, 8); // 直接用系统滴答时钟
你想想看,系统滴答时钟在设备重启后会重置。如果门锁断电再上电,IV就会从同一个值开始。攻击者只要抓取两次重启后的加密包,就能做IV重用攻击。
更离谱的是,有些厂商直接用全零的IV:
// 我见过的最离谱的实现
uint8_t iv[8] = {0}; // 固定IV,从未改变
这种实现,说白了就是给攻击者送人头。攻击流程很简单:
- 抓取两个使用相同IV的加密包
- C1 = P1 XOR KeyStream
- C2 = P2 XOR KeyStream
- C1 XOR C2 = P1 XOR P2
- 如果知道P1的部分内容(比如固定协议头),就能还原P2
避坑指南:我曾经在一个医疗设备项目里发现,设备每次连接都使用相同的IV。原因是工程师把IV写死在代码里了。修复方法很简单——用真随机数生成器,或者至少用硬件随机数+设备唯一ID组合。
数据包完整性校验绕过:MIC不是万能的
MIC(消息完整性校验码)是CCM模式的一部分,用来防止数据被篡改。但MIC的保护范围是有限的。
BLE的数据包结构是这样的:
| 前导码 | 访问地址 | PDU头 | payload | MIC |
| 1字节 | 4字节 | 2字节 | 可变长度 | 4/8字节 |
注意看,前导码、访问地址、PDU头都不在MIC的保护范围内。这意味着攻击者可以修改这些字段而不被检测到。
我记得有一次做渗透测试,发现一个蓝牙手环的固件更新流程存在漏洞。攻击者可以修改PDU头里的长度字段,让接收端解析错误的payload长度,导致缓冲区溢出。
具体攻击手法:
- 抓取合法的加密数据包
- 修改PDU头中的长度字段(比如从20改成200)
- 重放修改后的包
- 接收端解析时,认为payload有200字节,但实际只有20字节
- 接收端读取后续内存数据作为payload,造成信息泄露
我的建议:在应用层再做一层完整性校验。BLE的MIC只保护了payload,但应用层应该对关键字段(如长度、序号)做额外的校验。别把所有信任都交给底层协议。
加密降级攻击:让你用回破锁
加密降级攻击是BLE安全里最经典的攻击方式之一。攻击者通过干扰配对过程,让双方使用最低安全等级的加密方式。
BLE的加密等级从低到高:
| 等级 | 加密方式 | 密钥长度 | 安全性 |
|---|---|---|---|
| 1 | 无加密 | N/A | 极低 |
| 2 | LE Legacy配对 | 16字节 | 低 |
| 3 | LE Secure Connections | 16字节 | 高 |
| 4 | LE Secure Connections + MITM保护 | 16字节 | 最高 |
攻击者怎么做?很简单——在配对请求/响应阶段,修改双方支持的加密特性字段。
// 正常的配对请求
Pairing Request:
IO Capability: KeyboardOnly
OOB Data Flag: OOB not present
AuthReq: Bonding | MITM | Secure Connections
Maximum Encryption Key Size: 16
Initiator Key Distribution: EncKey | IdKey
Responder Key Distribution: EncKey | IdKey
// 攻击者修改后的配对请求
Pairing Request:
IO Capability: NoInputNoOutput
OOB Data Flag: OOB not present
AuthReq: Bonding (无MITM, 无Secure Connections)
Maximum Encryption Key Size: 7 // 降级到7字节!
Initiator Key Distribution: EncKey
Responder Key Distribution: EncKey
你想想看,如果双方都支持Secure Connections,但攻击者把配对请求里的Secure Connections标志位清掉,双方就会回退到Legacy配对。Legacy配对的密钥交换是明文传输的,攻击者可以轻松窃听。
关键点:降级攻击的核心是MITM(中间人)在配对阶段篡改加密能力协商消息。防御方法是在应用层验证最终的加密参数,或者强制使用最高安全等级。
SVG流程图:BLE加密攻击全景
实战中的防御建议
说了这么多漏洞,总得给点解决方案。我总结了几条实战经验:
- IV生成必须用真随机数。别偷懒用时间戳或计数器。硬件随机数生成器(TRNG)是最好的选择。
- 强制使用LE Secure Connections。在应用层检查配对后的加密等级,如果低于预期就断开连接。
- 应用层加一层完整性校验。对关键数据字段做HMAC或数字签名,别完全依赖BLE的MIC。
- 密钥协商完成后,双方交换随机挑战值。防止攻击者在配对过程中篡改密钥。
- 固件更新时使用独立的加密通道。别复用BLE的加密会话,防止降级攻击影响固件更新。
我的经验:有一次做产品安全审计,发现设备在配对成功后没有验证最终的加密参数。攻击者可以轻松降级到无加密模式。修复方法很简单——在配对完成后,双方交换一个加密的“安全确认”消息,包含协商的加密等级和密钥长度。如果匹配不上,立即断开。
BLE加密看似坚固,但实现上的小疏忽就能让整个安全体系崩塌。记住,安全不是靠协议本身,而是靠正确的实现。你想想看,再好的锁,如果钥匙随便放,跟没锁有什么区别?