4. 单向认证机制:设备向服务器证明身份,服务器不向设备证明身份的场景与实现

单向认证,说白了就是只有设备需要证明“我是谁”,服务器不需要向设备亮明身份。你可能会问:服务器不证明自己,设备怎么知道它连的是真服务器?

嗯,这个问题问得好。在实际的 IoT 场景里,这种“不平等”的信任关系其实非常普遍。我做过好几个项目,设备端资源极其有限——CPU 主频几十兆赫,RAM 几百 KB,跑完整的 TLS 双向握手简直要命。这时候单向认证就成了务实的选择。

4.1 什么场景下必须用单向认证?

我个人习惯把场景分成三类,你对照着看就清楚了:

场景类型 典型例子 为什么单向就够了
资源受限设备 温湿度传感器、智能灯泡 跑不动完整 TLS 握手,证书链验证太耗内存
服务器身份可预置 企业内网网关、私有云平台 服务器地址和公钥在出厂时已经烧录,无需动态验证
数据上报为主 电表读数、环境监测 设备只发数据不接收敏感指令,被仿冒服务器也没收益

我记得有一次做智能水表项目,MCU 只有 64KB 闪存。全栈 TLS 1.2 握手需要额外 20KB 左右的堆空间,根本塞不下。最后我们选了单向认证 + 预置服务器公钥的方案,握手开销直接砍掉一半。

核心原则:单向认证不是“偷工减料”,而是针对威胁模型做减法。如果设备被仿冒服务器的损失可控,单向认证就是性价比最高的选择。

4.2 单向认证的两种主流实现方式

实际落地时,我见过两种做法。一种基于预共享密钥(PSK),另一种基于证书。咱们分别看看。

4.2.1 基于 PSK 的单向认证

这种方式最简单。设备和服务器预先约定一个对称密钥,设备用这个密钥证明身份。

流程大致是这样:

  1. 设备发起连接,携带设备 ID
  2. 服务器返回一个随机数(nonce)
  3. 设备用 PSK 对 nonce 做 HMAC,把结果发给服务器
  4. 服务器用同样的 PSK 验算 HMAC,一致则通过

代码示例(伪代码风格):

// 设备端
device_id = "sensor_001"
nonce = recv_from_server()
hmac = HMAC_SHA256(psk, nonce + device_id)
send_to_server(device_id, hmac)

// 服务器端
expected_hmac = HMAC_SHA256(lookup_psk(device_id), nonce + device_id)
if received_hmac == expected_hmac:
    accept()
else:
    reject()

我的经验:PSK 方案最大的坑是密钥分发。我曾经见过一个项目,所有设备用同一个 PSK,结果一台设备被破解,整个网络都沦陷了。记住:每台设备必须用独立的 PSK,而且 PSK 要足够随机。

4.2.2 基于证书的单向认证

这种方式更灵活,适合设备数量大、需要动态管理的场景。

流程如下:

  1. 设备持有设备证书和私钥
  2. 设备发起 TLS 连接,在 ClientHello 中携带证书
  3. 服务器验证证书链:设备证书 → 中间 CA → 根 CA
  4. 验证通过后,服务器用设备公钥加密一个随机数,设备用私钥解密并返回
  5. 服务器确认设备持有私钥,认证完成

这里要注意:服务器不需要提供自己的证书,所以 TLS 握手只有 2 个来回(正常双向是 3 个)。

避坑指南:我曾经遇到一个坑——设备证书过期了,但设备没有 NTP 同步时间,导致证书验证永远失败。解决方案:要么设备支持 OTA 更新证书,要么在证书有效期上留足余量(比如 10 年),要么用 PSK 做降级兜底。

4.3 单向认证的威胁模型分析

单向认证不是万能的。咱们得清楚它防什么、不防什么。

我画了一张图,帮你理清逻辑:

单向认证威胁模型 IoT 设备 持有证书/PSK 云服务器 验证设备身份 设备证书 + 签名 攻击者(仿冒服务器) 可拦截、可重放 仿冒服务器 中间人攻击 单向认证不防中间人攻击 如果攻击者仿冒服务器,设备无法察觉。解决方案:预置服务器公钥或使用带外验证。

从图上你能看到:设备向服务器证明身份这条链路是安全的,但服务器到设备的方向是“裸奔”的。攻击者可以仿冒服务器,设备无法验证。

那怎么办?我一般用三个手段来弥补:

  • 预置服务器指纹:在设备固件里硬编码服务器证书的 SHA256 指纹,设备连接时比对
  • 带外验证:设备首次连接后,通过短信、邮件等方式让管理员确认服务器身份
  • 应用层加密:即使通道被中间人,设备上报的数据本身也是加密的(比如用 PSK 加密 payload)

4.4 单向认证的工程落地 checklist

最后,我整理了一份清单。每次做单向认证方案时,我都会对着它过一遍:

检查项 说明 优先级
密钥唯一性 每台设备使用独立的 PSK 或证书 P0
密钥存储安全 私钥必须存储在安全元件(SE)或 TEE 中 P0
防重放攻击 每次认证必须包含 nonce 或时间戳 P0
证书有效期管理 设备需支持 OTA 更新证书,或使用长有效期证书 P1
服务器身份兜底 预置服务器公钥指纹,或使用应用层加密 P1
日志与审计 记录每次认证的 device_id、时间、结果 P2

一句话总结:单向认证不是偷懒,而是精准的威胁模型取舍。选对场景、管好密钥、补上服务器身份验证的短板,这套方案在资源受限设备上能跑得很稳。