Skip to content

威胁模型

如果你认为"只要用了HTTPS就安全了"或者"MQTT Broker的ACL就够了",那么这份文档就是为你准备的。

问题背景

在点对点通信中,当你收到一个数据包时:

  • 如何确认它真的来自声称的发送者?
  • 如何确认发送者有权限执行该操作?
  • 如何防止消息被窃听或篡改?

常见的错误认知

错误认知问题
"MQTT ACL够用了"ACL只控制谁能发布到哪个主题,不验证消息内容真实性
"用了TLS就安全"TLS只保护传输层,不支持蓝牙等非TCP传输
"JWT可以解决一切"每条消息带JWT = 542字节开销,蓝牙场景不可接受
"加密了就不会被篡改"大错特错! 加密≠认证,没有Tag的密文可以被精确修改

核心挑战

我们的场景

多个客户端(手机、门锁、服务器)需要互相通信,但:

  1. 客户端之间如何鉴别对方身份?

    • 不能总是依赖中心服务器
    • 蓝牙场景下完全离线
  2. 如何验证对方权限?

    • 不能把权限写死在代码里
    • 需要灵活管理
  3. 如何保护消息?

    • 不能被窃听(机密性)
    • 不能被篡改(完整性)
    • 不能被重放(新鲜性)

传输方式的多样性

我们需要支持:

传输方式特点TLS可用?
MQTT通过Broker中继✅ 可以
蓝牙BLE真正的离线P2P❌ 不可以
WiFi Direct局域网P2P❌ 一般不用
未来传输未知❌ 不确定

结论:不能依赖传输层安全(TLS),必须在应用层解决安全问题。

设计思路演进

尝试1:每条消息JWT签名

json
{
  "payload": {...},
  "jwt": "eyJhbGciOiJFZDI1NTE5..."
}

问题

  • JWT太长(Header + Payload + Signature = 542字节)
  • 即使用Ed25519签名也需86字节
  • 蓝牙BLE的MTU仅23字节,完全不可接受

尝试2:对称密钥签名

客户端A和B共享同一个secret,用HMAC签名

问题

  • 对称密钥意味着双方都能伪造对方的消息
  • 一旦泄露,整个系统崩溃
  • 无法区分谁发的消息

尝试3:mTLS客户端证书

每个设备有自己的X.509证书,TLS层验证身份

问题

  • 依赖TLS层,蓝牙不可用
  • 证书管理复杂
  • 不满足"传输层无关"要求

最终方案:会话协商

借鉴HTTPS的思路:

  1. 握手阶段(可以大):交换身份凭证,协商密钥
  2. 通信阶段(必须小):用会话密钥加密+认证

关键安全原则

1. 自证明身份

Device ID = Base58(Ed25519公钥)

  • 身份即公钥,无需第三方证明
  • 能用私钥签名的,必定是该设备
  • 借鉴:libp2p、IPFS

2. 身份与权限解耦

Credential证明"你是谁",权限表决定"你能做什么"

  • Credential由认证服务器签发,永久有效
  • 权限表存储在设备端,可随时更新
  • 撤销用户?从权限表删除uid即可

3. 加密必须带认证

没有Tag的加密 = 没有锁的保险箱

ChaCha20等流加密的XOR特性导致:

python
# 攻击者截获密文(不知道密钥!)
ciphertext = intercept()

# 知道JSON格式,猜测 {"a":3} (查询)
# 想改成 {"a":1} (解锁)

# 直接修改密文
tampered[offset] ^= ord('3') ^ ord('1')

# 门锁解密 → 得到 {"a":1} → 门开了!

必须使用AEAD(如ChaCha20-Poly1305):加密+认证一体化,任何篡改都会被检测。

4. 前向安全

每次会话使用临时密钥对:

  • 会话结束后销毁临时密钥
  • 即使长期私钥泄露,历史会话仍安全
  • 借鉴:TLS 1.3、Signal Protocol

5. 纵深防御

不依赖单一防护层:

  • 传输层:可选TLS(如果传输支持)
  • 会话层:握手协商,身份验证
  • 应用层:权限表,业务逻辑检查

为什么不能偷懒?

场景1:只加密不认证

"我用AES加密了,很安全吧?"

错! 攻击者可以:

  • 位翻转攻击:不知道密钥也能精确修改消息
  • 已知明文攻击:猜测格式后构造有效密文
  • 结果:门锁在你不知情的情况下被打开

场景2:信任Broker ACL

"MQTT Broker的ACL控制了谁能发消息给我,够了吧?"

错! ACL无法:

  • 验证消息内容是否被篡改
  • 验证发送者的Ed25519签名
  • 阻止Broker被入侵后的恶意消息

场景3:硬编码权限

"我在代码里写死了谁有什么权限,改不了。"

错! 会导致:

  • 无法撤销权限(用户离职了怎么办?)
  • 无法临时授权(朋友来访怎么办?)
  • 固件更新才能改权限(不现实)

技术选型总结

组件选择原因
签名算法Ed2551932字节公钥,64字节签名,安全高效
密钥交换X25519 ECDH前向安全,临时密钥协商
加密认证ChaCha20-Poly1305AEAD一体化,软件实现快,适合嵌入式
序列化CBOR二进制JSON,比JSON小50%+
编码Base58无易混淆字符,适合手动输入

下一步

根据你的安全需求,选择合适的方案:

物联网设备通信协议文档