1. Keystore 与蓝牙持久化概述
1.1 核心概念
Keystore 是一个基于硬件或强隔离软件的安全密钥存储容器,用于生成、保存和使用加密密钥,且保证密钥材料永不离开安全边界。在 Android 平台上对应 AndroidKeyStore,在嵌入式领域则通常由 HSM(硬件安全模块) 或 TEE(可信执行环境) 提供等效能力。
蓝牙持久化 是指蓝牙协议栈将配对信息、连接参数、设备标识、LTK(长期密钥)、IRK(身份解析密钥)等敏感数据写入非易失性存储(如 Flash、NFS)以便后续连接时复用。这些数据一旦泄露,攻击者可冒充已配对设备、解密历史通信或绕过身份认证。
Keystore 加密在蓝牙持久化中的核心价值:将蓝牙持久化数据从“明文存储”转变为“密钥由 Keystore 保护、密文写入持久层”,使得即使攻击者物理获取存储介质,也无法还原原始密钥或配对凭证。
设计原则:密钥永不离“柜”,持久层只存密文;每次使用密钥都通过 Keystore 硬件完成加解密操作,应用层仅持有密文和句柄。
1.2 系统架构
下图展示了 Keystore 加密在蓝牙持久化中的端到端数据流,包含发送方、接收方、传输信道、加解密模块以及持久化存储,并标出核心威胁点。
1.3 应用场景
Keystore 加密的蓝牙持久化在以下四类场景中需求最为迫切,威胁暴露面也各不相同:
| 应用场景 | 持久化数据示例 | 主要威胁 | Keystore 防护价值 |
|---|---|---|---|
| 物联网设备配对 | LTK、IRK、设备地址白名单 | 物理读取 Flash 提取密钥 | 硬件隔离,密钥不可导出 |
| 可穿戴设备数据同步 | 配对记录、历史健康数据加密密钥 | 中间人攻击、重放同步请求 | 信道加密 + 持久化密文绑定设备 |
| 汽车蓝牙钥匙 | 数字钥匙证书、会话密钥 | 重放攻击、物理克隆 | 动态密钥协商 + 防回滚存储 |
| 医疗设备数据传输 | 患者数据加密密钥、配对审计日志 | 数据泄露、篡改历史记录 | 端到端加密 + 持久化完整性校验 |
场景选择建议:只要蓝牙持久化数据包含“可重复用于认证或解密的秘密”,就应考虑引入 Keystore。
如果设备只做无绑定广播(如 Beacon),则无需使用 Keystore 保护。
1.4 常见威胁模型
蓝牙持久化面临的攻击可归纳为以下五类,Keystore 加密对其有不同程度的缓解效果:
-
物理存储读取 — 攻击者通过拆解设备、读取 Flash / eMMC 直接获取持久化数据。
缓解:Keystore 确保密钥仅存在于安全区,持久层只有密文,物理读取无效。 -
侧信道分析 — 通过功耗、电磁辐射或运行时间推测密钥信息。
缓解:硬件 Keystore 内置掩码与恒定时间比较,大幅提高分析成本。 -
蓝牙中间人攻击 — 攻击者在配对或重连过程中劫持空中信道,窃听或篡改数据。
缓解:Keystore 提供身份认证密钥,结合 Secure Connections 可有效阻断。 -
重放攻击 — 攻击者捕获历史配对请求或加密数据包,在后续重放以欺骗接收方。
缓解:Keystore 配合随机数生成器 + 计数器模式,使每次会话密钥唯一。 -
持久化数据篡改 — 攻击者修改持久层中的配对参数或公钥,诱导设备使用恶意配置。
缓解:Keystore 签名持久化数据块,验证失败则拒绝加载。
常见误区:Keystore 不能防范所有侧信道攻击(如简单功率分析仍可能泄漏操作类型),
也不能防御已取得 Root 或物理 JTAG 调试权限的攻击者对运行内存的直接转储。
因此 Keystore 应与其他安全机制(安全启动、内存加密、SE Linux)配合使用。
1.5 技术基础:Keystore API 示例
以下以 Android KeyStore 为例,展示生成 AES 密钥并用于加密蓝牙配对数据的核心流程。
实际嵌入式平台(如 NXP SE050、ST SAFE)API 不同,但逻辑结构一致。
// 1. 获取 KeyStore 实例并加载
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
// 2. 生成 AES-GCM 密钥(仅用于蓝牙持久化加密)
KeyGenerator keyGen = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"bluetooth_pairing_key_v1",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(256)
.build();
keyGen.init(spec);
SecretKey key = keyGen.generateKey();
// 3. 使用该密钥加密蓝牙 LTK 等敏感数据
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV();
byte[] encryptedPairData = cipher.doFinal(ltkRawBytes);
// 4. 将 IV + 密文写入持久化存储
saveToPersistentStorage(encryptedPairData, iv);
关键点:密钥别名
"bluetooth_pairing_key_v1" 由 KeyStore 管理,
应用层无法获取密钥原始字节;每次加解密必须通过 KeyStore 句柄调用硬件完成。
1.6 本课程的技术路线
后续章节将围绕以下主线展开:从 Keystore 初始化 → 蓝牙持久化数据建模 → 加解密集成 → 单元测试 → 性能调优 → 部署与 OTA 安全更新。第 2 章开始将深入具体平台的 Keystore 初始化与密钥生命周期管理。