4、数据通道PDU解析:LL Data PDU与加密数据包分析

抓包抓了这么多,你会发现大部分流量都在数据通道上。广告通道只是敲门砖,真正干活的全在数据通道。今天我们就来拆解这些PDU,看看它们到底长什么样。

我个人习惯把数据通道PDU分成三大类:数据PDU、控制PDU,还有加密后的数据包。咱们一个一个说。

4.1 LL Data PDU:Empty PDU与LLID区分

先看数据PDU。它的头部只有2个字节,但信息量不小。

字段 长度 说明
LLID 2 bits 逻辑链路标识符,区分数据包类型
NESN 1 bit 下一个期望的序列号
SN 1 bit 当前包的序列号
MD 1 bit 更多数据标志
RFU 3 bits 保留位
Length 8 bits Payload长度

LLID是关键。它只有2个bit,但决定了这个包怎么解析:

  • 00:LL Data PDU,空包或包含LL控制帧
  • 01:LL Data PDU,连续数据片段
  • 10:LL Data PDU,完整数据或起始片段
  • 11:保留

你可能会问,为什么要有空包?

嗯,这里要注意。空包(Empty PDU)在BLE里非常常见。它没有Payload,Length字段为0。它的作用就是确认——告诉对方“我收到你的包了,但没数据要发”。

核心要点:Empty PDU的LLID固定为01。抓包时看到大量LLID=01且Length=0的包,别慌,那是正常的ACK行为。

我在项目中遇到过一个问题:有个设备功耗一直下不来。抓包一看,空包发得太频繁了。后来调整了连接间隔和空包策略,功耗直接降了30%。

4.2 控制PDU:LL_VERSION_IND、LL_ENC_REQ等

控制PDU藏在数据PDU里。当LLID=00时,Payload的第一个字节就是Opcode,用来区分具体控制命令。

常见的控制PDU有这些:

Opcode 名称 用途
0x01 LL_CONNECTION_UPDATE_IND 更新连接参数
0x02 LL_CHANNEL_MAP_IND 更新信道映射
0x03 LL_TERMINATE_IND 终止连接
0x05 LL_VERSION_IND 交换版本信息
0x06 LL_FEATURE_REQ 请求特性支持
0x07 LL_FEATURE_RSP 响应特性支持
0x08 LL_ENC_REQ 加密请求
0x09 LL_ENC_RSP 加密响应
0x0A LL_START_ENC_REQ 开始加密请求
0x0B LL_START_ENC_RSP 开始加密响应

拿LL_VERSION_IND举个例子。它的Payload结构是这样的:

LL_VERSION_IND:
  Opcode: 0x05 (1 byte)
  Version: 1 byte (蓝牙核心规范版本号)
  Company ID: 2 bytes (公司标识符)
  Subversion: 2 bytes (子版本号)

抓包时看到这个包,说明两个设备在互相确认对方的协议栈版本。我建议你重点关注Version字段。如果一个是5.0,一个是4.2,有些特性可能就不支持。

再说LL_ENC_REQ。这是加密流程的起点。它的Payload包含:

  • Rand:8字节随机数
  • EDIV:2字节加密多样性因子
  • SKDm:8字节主设备会话密钥贡献值
  • IVm:4字节主设备初始向量贡献值

我曾经调试过一个加密失败的问题。抓包看到LL_ENC_REQ发出去后,对方回了LL_ENC_RSP,但紧接着就断连了。后来发现是EDIV不匹配——两边用的加密参数没对上。

调试技巧:抓包时如果看到加密流程中断,先检查LL_ENC_REQ和LL_ENC_RSP里的Rand和EDIV是否一致。不一致的话,大概率是配对过程出了问题。

4.3 MIC与加密数据包分析

加密后的数据包,结构会变。Payload后面会多出4个字节的MIC(消息完整性校验码)。

加密数据包的格式:

| 前导码 | 访问地址 | PDU头 | Payload(加密) | MIC(4字节) | CRC |

MIC是怎么算的?它基于AES-CCM加密算法。简单说,就是用LTK(长期密钥)和当前包的Packet Counter、Direction、IV等参数,算出一个校验值。

抓包时,加密后的Payload是看不到明文内容的。但你可以通过MIC来判断数据是否被篡改过。

我记得有一次,客户反馈说设备偶尔会断开连接。抓包一看,有个包的MIC校验失败了。排查下来,是射频干扰导致数据在传输过程中被损坏,MIC自然对不上。设备端检测到MIC错误,直接断连了。

注意:MIC校验失败不一定是攻击。射频环境差、数据包被截断、或者两端加密参数不一致,都可能导致MIC错误。别一看到MIC失败就怀疑是安全问题。

加密数据包的分析,说白了就是看MIC。如果MIC正确,说明数据完整且未被篡改。如果MIC错误,那这个包就得扔掉。

下面这张图展示了加密数据包的完整结构:

加密数据包结构 前导码 访问地址 PDU头 Payload(加密) MIC CRC 关键说明 1. 加密后,Payload内容不可见,但长度不变 2. MIC由AES-CCM算法基于LTK、Packet Counter、Direction、IV计算 3. MIC校验失败 → 数据被篡改或传输错误 → 设备断连 4. 抓包工具无法解密Payload,但可以显示MIC是否正确 5. 加密后,CRC仍然存在,用于检测物理层错误

抓包时,如果你看到加密数据包,别指望能看到明文。但你可以通过MIC来验证数据完整性。如果MIC连续失败,那基本可以断定链路质量有问题。

我个人习惯在抓包时同时关注两个指标:CRC错误率和MIC错误率。CRC错误多,说明物理层有问题。MIC错误多,说明加密层有问题。两者结合,定位问题会快很多。

实战建议:在抓包工具里设置过滤条件,只显示MIC错误的包。这样能快速定位到有问题的数据包,不用在成千上万个包里手动翻。

好了,数据通道PDU的内容就这些。记住三个重点:LLID区分数据类型、控制PDU管理连接、MIC保证加密数据完整性。抓包时多留意这些细节,很多问题一眼就能看出来。