1. GATT 协议基础与敏感数据传输场景
蓝牙 GATT(Generic Attribute Profile)定义了两个 BLE 设备之间如何通过 服务(Service)与 特征值(Characteristic)进行结构化数据交换。在敏感数据持久化场景中,GATT 是主机(手机/平板)与从机(嵌入式设备/传感器)之间传输原始敏感载荷的唯一通道。理解 GATT 的层级、通信原语以及传输限制,是实现安全加密持久化的前置条件。
1.1 GATT 层级结构与通信模型
| 层级 | 角色 | 举例(心率传感器) |
|---|---|---|
| Profile | 高层规范,组合多个 Service | 心率 Profile |
| Service | 功能分组,UUID 唯一标识 | 心率服务 0x180D |
| Characteristic | 具体数据单元,包含 Value & 属性 | 心率测量 0x2A37 |
| Descriptor | 特征值的附加元数据 | CCCD(客户端特征配置描述符) |
交互流程始终由 GATT Client(通常为主机)发起请求,GATT Server(通常为从机)响应。敏感数据写入时,Client 通过 Write Request 将加密后的载荷写入 Server 的 Characteristic Value;读取时通过 Read Request 或 Notification 获取。
关键事实: 即使传输层已配置加密(Secure Connections),Application Payload 仍应在写入 Characteristic 之前由上层应用完成独立加密。GATT 本身不提供端到端机密性。
1.2 传输原语:读写、通知与安全限制
- Read / Write:同步操作,必须等待 ATT 响应;单次最大载荷为
MTU - 3字节。 - Notify / Indicate:Server 主动推送数据,Client 不返回 ACK(Notify)或返回 ACK(Indicate);适用于流式敏感数据上报。
- 数据长度限制:默认 MTU 为 23 字节,有效载荷仅 20 字节。通过 MTU 协商可将单帧提升至 247+ 字节(以底层 Controller 能力为准)。
- 安全通道要求:蓝牙 4.2+ 支持 LE Secure Connections(ECDH 密钥协商 + AES-CCM 加密)。特征值属性需将
need_encryption或need_authentication置位,强制 Link Layer 加密。
实践建议: 将敏感特征值的属性设置为
CCCD + Read + Write + Encryption Required,确保在没有成功配对的情况下任何 ATT 请求都被底层拒绝。
1.3 敏感数据传输典型场景
- 密钥材料注入:主机向设备写入加密后的 Keystore 种子或 AES 密钥。
- 日志/取证数据提取:从机通过 Notify 将加密存储的日志逐段推送给主机。
- 远程锁定/擦除命令:主机写入一条经过签名的指令特征值,从机验证后执行本地 Keystore 擦除。
1.4 安全通道建立流程(链路层)
| 步骤 | 描述 | 影响 |
|---|---|---|
| 1. Pairing Feature Exchange | 双方交换 IO Capabilities、AuthReq 等 | 确定是否启用 MITM |
| 2. LE Secure Connections 密钥协商 | ECDH P-256 生成 LTK 和 CSRK | 提供 128-bit AES 加密 |
| 3. Encryption Setup | LL_ENC_REQ/LL_ENC_RSP 启用链路加密 | 所有 ATT PDU 被加密 |
| 4. GATT Service Discovery | Client 重新发现服务特征 | 确定哪些特征受加密保护 |
链路层加密只保护射频传输路径,不保护内存中的敏感数据。因此本课程的后续章节将聚焦于 应用层加密 + 本地 Keystore 持久化,而非依赖蓝牙链路单独提供安全边界。
1.5 GATT 敏感数据交互结构图
1.6 常见错误与规避
- MTU 协商失败:单帧写 20 字节以上时,未协商 MTU 导致 ATT 错误。应在连接建立后立刻发起
MTU Exchange Request。 - 未设置加密属性:特征值的
need_encryption未使能,导致即使链路已加密,敏感数据仍可通过未加密的 Read 请求被读取。 - 遗漏 CCCD 注册:使用 Notification 时未写入 CCCD 使能值 0x0001,导致从机永不推送数据。
- 假设 GATT 提供端到端安全:链路层加密仅保护空中接口,不能保证数据在主机/从机本地内存中的安全。
1.7 性能与稳定性优化关注点
| 维度 | 建议 | 效果 |
|---|---|---|
| MTU 优化 | 连接后协商至最大支持 MTU(如 247) | 单帧写入量提升 12 倍,减少 ATT 交互次数 |
| 写模式选择 | 大块数据使用 Write Long (Prepare + Execute) 或分段 Notify | 避免 ATT 层重组错误 |
| 加密后重连 | 每次重连后检查加密状态,未加密则拒绝 GATT 操作并重新配对 | 防止残留绑定未加密 |
| 缓冲区管理 | 从机接收 Buffer 应大于 MTU 大小,防止溢出丢弃 | 提高大载荷写入成功率 |
安全警告: 即使在 GATT 层启用了加密,也不应将未加密的敏感数据(如明文 AES 密钥)直接写入特征值。始终在应用层对 Payload 进行独立加密 + 完整性校验,只将密文交付 GATT 传输。