IoT 设备身份建立:从 PIN/PAKE 到 AuthCode 会话

摘要

IoT 设备首次接入和日常控制面对的是两类不同问题:首次接入时,设备可能只有 PIN,没有长期身份;日常控制时,系统则需要低开销地验证控制端并复用安全会话。

本文说明 PIN/SPEKE、CloudSetup、AuthCode 与本地控制 Session 的关系:它们不是替代方案,而是身份建立链路中的不同阶段。

1. 网络、身份和会话是三件不同的事

IoT 接入流程中有三个容易混淆的概念:

  • 网络连接:设备是否拥有 IP,双方是否可达;
  • 设备身份:控制端正在访问的是否是预期设备;
  • 安全会话:双方是否拥有一致的临时密钥和消息序列状态。

    img


    设备连上 Wi-Fi 只完成第一层。没有身份时,控制端不能安全地下发长期凭据;没有 Session 时,也不能高效执行后续控制。

2. 首次接入的威胁模型

首次接入通常面临以下风险:

  1. PIN 空间有限,不能把 PIN 本身当作长期密钥;
  2. 本项目基于 UDP 的本地 CoAP 通信可能被监听、重放或伪造;
  3. 控制端需要确认设备确实持有相同 PIN;
  4. 设备身份尚未建立,无法直接执行 AuthCode 校验;
  5. 首次配置成功后,不应继续依赖固定 PIN 执行所有业务控制。

PIN/SPEKE 的目标是在设备没有长期身份时,利用双方已知 PIN 建立临时安全通道,而不是永久替代 AuthCode。

3. 身份材料分别解决什么问题

字段 作用
devId 设备的逻辑身份
authCodeId 标识本次使用哪一份认证材料
authCode 参与认证或会话密钥派生的安全材料
uidHash CloudSetup 中的用户或授权关联字段
PUUID 控制端的应用层稳定标识,不是密码学凭据
sessId 标识一次已经协商完成的控制 Session

authCodeId 不是密钥,更像认证材料的索引;双方仍需持有匹配的 authCode 等安全输入。sessId 也不是设备身份,它必须与会话密钥、序列号和有效期一起使用。当前 AuthCode 建链中,authCode 是认证与派生输入,uidHash 则是 CloudSetup 的关联字段,不应混为同一类密钥材料。

4. PIN/SPEKE:建立临时安全通道

设备尚未拥有 devId/authCodeId 时,控制端可以使用 PIN 发起本组件中称为 SPEKE 的 PAKE 类协商。

img

SPEKE 成功表示双方建立了临时安全通道,但设备仍处于“未身份化”状态。此时可以安全下发身份信息,却不应把该通道误认为长期本地控制 Session。安全性还依赖双方随机数、消息校验和密钥确认的正确实现;PAKE 不消除弱 PIN、在线猜测、端点泄露等风险。

5. CloudSetup:改变设备身份状态

CloudSetup 的核心作用是把设备从“未身份化”迁移到“已身份化”。

img

CloudSetup 请求通常包含 devId、authCodeId、authCode 和 uidHash,应通过已建立的安全通道传输。

CloudSetup 成功不表示 5686 本地控制 Session 已自动创建。身份状态改变后,控制端应重新发现设备并进入 AuthCode 连接流程;5686 是本项目的本地控制端口。

6. AuthCode:验证长期本地控制身份

设备已发布 devId 和 authCodeId 后,控制端可以使用匹配认证材料请求创建本地控制 Session。

img

AuthCode 路径适合长期控制,因为它不需要每条命令重新执行 SPEKE,并且可以为每个 Session 维护独立序列号、有效期和加密状态。

7. 两条身份建立路径与会话边界

设备经 BLE 同时获得网络和身份配置时,入网后可直接走 AuthCode;若 BLE 只完成配网,则通过 PIN/SPEKE 与 CloudSetup 补充身份,再重新发现并创建 AuthCode Session。两种路径不同,但最终都回到“身份已写入、会话已创建”的同一状态。

身份材料用于证明“双方是谁”,会话密钥用于保护“本次通信”。正确生命周期为:

img

会话密钥不应写入日志,也不应在设备找不到 Session 时绕过校验继续执行命令。设备重启后内存会话丢失属于正常情况,控制端应重新创建 Session。

8. 密钥派生与数据加密

密钥派生函数负责把口令、认证材料、随机数等输入转换成固定长度密钥。它与加密算法解决的问题不同:

能力 解决的问题
PBKDF2 增加低熵口令推导成本,生成固定长度材料
HKDF 从已有高熵秘密派生不同用途的子密钥
AES-GCM 在认证标签被验证时,为业务数据提供机密性和完整性保护

当前工程中,本地控制 AuthCode 会话和 SPEKE 协议版本可能走不同的派生组合。协议双方必须在算法、摘要类型、salt、info、迭代次数和输出长度上完全一致。任何一个字段不同,最终都表现为“请求到达但解密失败”。

AES-GCM 要求同一密钥下 IV/Nonce 唯一;若实现以 sequence 构造 IV,sequence 必须单调且不能回退。sequence 是协议字段,并不天然等同于 IV,最终应以具体 IV 构造实现为准。

身份材料应来自可信服务、生产系统或安全绑定流程。离线联调可使用预置测试材料,但不得复用于量产设备,也不应写入公开日志。

9. 安全失败时如何处理

失败位置 正确行为
SPEKE 参数或证明无效 终止临时协商,不创建 Session
CloudSetup 解密失败 不修改设备身份
身份字段缺失 返回明确错误,保持原状态
身份持久化失败 不发布新的 authCodeId
AuthCode 不匹配 拒绝创建本地控制 Session
Session 响应校验失败 不保存、不初始化、不发送控制命令
业务命令认证失败 失效当前 Session,要求重新连接

失败处理的核心是避免“半成功状态”。系统宁可重新协商,也不应保留字段不完整或双方理解不同的身份记录。

10. 验证思路

验证身份链路时,应分别观察:

  1. 未身份化设备的发现响应是否缺少 authCodeId;
  2. SPEKE 是否完成双向协商;
  3. CloudSetup 是否返回成功且设备保存身份;
  4. 重新发现后是否发布 devId/authCodeId;
  5. AuthCode Session 是否成功创建;
  6. 控制命令是否使用新 Session,以及认证标签与 sequence 是否校验成功。

测试程序可以把 SPEKE 和 CloudSetup 拆开验证,也可以使用一键接口连续执行,但日志中必须能区分两个阶段。

至少覆盖正确/错误 PIN、CloudSetup 字段完整性、重新发现后的身份发布、AuthCode 建会话,以及设备重启后的旧会话失效与重建。

11. 总结

PIN/SPEKE 与 AuthCode 并不是重复设计。PIN/SPEKE 解决无长期身份设备的首次安全接入,CloudSetup 完成身份状态迁移,AuthCode 验证长期身份,本地控制 Session 则保护后续高频业务通信。

理解这四层关系后,就能准确区分“网络已连接”“临时安全通道已建立”“身份已写入”和“本地控制 Session 可用”四种不同状态。

参考

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐