3、通信协议安全:MQTT安全、CoAP安全、Zigbee安全、蓝牙Mesh安全

通信协议,说白了就是智能照明设备之间沟通的「语言」。语言不通,灯就亮不了;语言不安全,你家灯就可能被别人控制。我这些年做物联网安全,见过太多因为协议裸奔导致的问题。今天咱们就把这四种主流协议的安全机制掰开揉碎了讲。

3.1 MQTT安全:发布/订阅模型的护城河

MQTT是智能照明里用得最多的协议。轻量、省带宽,特别适合嵌入式设备。但轻量不代表可以裸奔。

核心要点:MQTT本身不提供加密,安全全靠外部加持。

3.1.1 传输层加密(TLS/SSL)

我建议所有MQTT通信都走TLS。为什么?因为MQTT的Payload是明文传输的。你想想看,如果有人抓包,你家灯的开关状态、定时策略全暴露了。

配置TLS时要注意:

  • 证书验证不能跳过:我在项目中遇到过,有人为了省事把verify设为false。结果中间人攻击直接穿透。
  • 使用双向认证:客户端和服务端互相验证证书。这样就算有人伪造Broker,也骗不了你的灯。
  • TLS版本别用太老的:TLS 1.0/1.1已经废了,至少用TLS 1.2。
// MQTT over TLS 配置示例(C语言)
MQTTClient client;
MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;

ssl_opts.enableServerCertAuth = 1;  // 必须开启
ssl_opts.trustStore = "/etc/ssl/certs/ca-cert.pem";
ssl_opts.keyStore = "/etc/ssl/certs/client.pem";
ssl_opts.privateKey = "/etc/ssl/certs/client.key";
ssl_opts.sslVersion = MQTT_SSL_VERSION_TLS_1_2;

opts.ssl = &ssl_opts;

我的经验:嵌入式设备内存有限,TLS握手开销不小。我一般建议用ECC证书代替RSA,握手速度快30%以上,内存占用也小。

3.1.2 应用层安全(用户名/密码 + ACL)

TLS解决的是传输加密,但认证还得靠应用层。MQTT支持用户名密码认证,但别用弱密码。

我曾经见过一个项目,所有灯都用同一个密码「123456」。结果被黑客扫到Broker端口,直接全屋灯被控制。嗯,那场面挺尴尬的。

更好的做法是:

  • 每个设备独立凭证:用设备ID+动态Token,Token定期更换。
  • ACL(访问控制列表):限制每个设备只能发布/订阅特定Topic。比如灯A只能发布「livingroom/light1/status」,不能去动「bedroom/light2/status」。

3.2 CoAP安全:RESTful风格的安全挑战

CoAP是类HTTP的协议,但跑在UDP上。它比MQTT更轻量,适合资源极度受限的设备。但UDP本身无连接,安全更难做。

3.2.1 DTLS:CoAP的TLS版本

CoAP的安全靠DTLS(Datagram TLS)。说白了就是给UDP包加了个加密壳。但DTLS有个坑——握手包可能丢包。

我记得有一次调试,灯总是连不上服务器。查了半天,发现是DTLS握手时丢了一个包,导致重传超时。后来我加了握手超时重试机制才解决。

// CoAP over DTLS 配置(基于libcoap)
coap_context_t *ctx;
coap_address_t dst_addr;
coap_session_t *session;

// 设置DTLS参数
coap_dtls_context_t *dtls_ctx;
dtls_ctx = coap_dtls_new_context(ctx);

// 加载证书
coap_dtls_set_psk(dtls_ctx, "client_identity", 
                  (uint8_t*)"pre_shared_key", 16);

session = coap_new_client_session(ctx, NULL, &dst_addr, 
                                   COAP_PROTO_DTLS);

注意:CoAP的默认端口是5683(非加密)和5684(DTLS加密)。千万别搞混了。我见过有人把加密数据发到非加密端口,结果数据全裸奔。

3.2.2 资源安全与访问控制

CoAP的每个资源都是一个URI。比如「coaps://server/light/1/status」。安全策略要细化到每个资源:

  • 读/写分离:控制命令(写)需要更高权限,状态查询(读)可以放宽。
  • 观察者模式安全:CoAP支持Observe机制(类似订阅)。要限制谁可以Observe你的灯状态。

3.3 Zigbee安全:网状网络的加密迷宫

Zigbee是智能照明的老牌协议。它用网状网络,设备之间可以互相中继。但网状网络也意味着攻击面更大——任何一个节点被攻破,都可能影响全网。

3.3.1 网络层安全(AES-128-CCM)

Zigbee强制使用AES-128-CCM加密。每个Zigbee网络都有一个Network Key,所有设备共享。但问题来了——如果Network Key泄露,整个网络就完了。

我建议的做法:

  • 使用Install Code:设备入网时,通过Install Code派生初始Key。这样就算抓包也拿不到明文Key。
  • 定期更新Network Key:Zigbee 3.0支持Key更新机制。我一般设成每30天换一次。

3.3.2 应用层安全(APS层加密)

除了网络层,Zigbee在应用层(APS)还有一层加密。这层用的是Link Key,设备之间点对点加密。

为什么要两层加密?你想想看,如果网络层Key被攻破,至少应用层数据还是加密的。这叫纵深防御。

层级 加密方式 作用范围 我的建议
网络层 AES-128-CCM 全网 必须开启,使用Install Code
APS层 AES-128-CCM 点对点 建议开启,尤其控制命令
ZCL层 无强制加密 应用数据 可加自定义加密

避坑指南:我曾经遇到过Zigbee设备入网时,Network Key通过空中明文传输。这太危险了。后来我强制所有设备都走Install Code方式入网,虽然麻烦点,但安全多了。

3.4 蓝牙Mesh安全:低功耗的加密艺术

蓝牙Mesh是后来者,但发展很快。它基于BLE,功耗极低,适合电池供电的传感器。但Mesh网络节点多,安全设计更复杂。

3.4.1 四层安全模型

蓝牙Mesh的安全分四层,每层干不同的事:

  • 网络层:用Network Key加密,防止未授权设备加入网络。
  • 传输层:用Application Key加密,确保只有特定应用能读懂数据。
  • 访问层:控制谁能访问特定Model(比如灯的开/关Model)。
  • 底层:BLE本身的加密(AES-CCM)。

说白了,就是层层设卡。一个灯泡要控制另一个灯泡,得先过网络层,再过传输层,最后看访问层给不给权限。

3.4.2 Provisioning过程的安全

蓝牙Mesh设备入网叫Provisioning。这个过程最容易出问题。我建议:

  • 使用OOB(带外)认证:比如扫描设备上的二维码,或者按按钮确认。别用默认PIN码。
  • 静态OOB vs 动态OOB:静态OOB是固定值,动态OOB每次不同。我推荐动态OOB,安全性高一个量级。
// 蓝牙Mesh Provisioning 安全配置示例
// 使用动态OOB认证
mesh_provisioner_t provisioner;
mesh_device_t device;

// 设置OOB类型为动态
provisioner.oob_type = MESH_OOB_DYNAMIC;
provisioner.oob_action = MESH_OOB_ACTION_INPUT;

// 设备端生成随机数
uint8_t random_oob[16];
generate_random(random_oob, 16);
device.oob_data = random_oob;

// 开始Provisioning
mesh_provision(&provisioner, &device);

重要提醒:蓝牙Mesh的Replay Protection(重放攻击防护)是基于Sequence Number的。如果设备断电后Sequence Number重置,就可能被重放攻击。我一般建议设备用非易失性存储保存Sequence Number,每次开机接着上次的用。

3.5 四种协议安全对比

最后做个总结。四种协议各有优劣,选型时得看场景:

协议 加密方式 认证机制 我最担心的点
MQTT TLS + 应用层 证书/用户名密码 Broker单点故障
CoAP DTLS PSK/证书 UDP丢包导致握手失败
Zigbee AES-128-CCM(双层) Install Code/Network Key Key泄露后全网沦陷
蓝牙Mesh AES-CCM(四层) OOB/Provisioning Sequence Number重置

我个人习惯是:能走TLS/DTLS的尽量走,不能走的(比如Zigbee)就靠密钥管理和定期更新。安全没有银弹,但做好这几点,至少能防住90%的常见攻击。

一句话总结:协议安全不是选出来的,是配出来的。再安全的协议,配置错了也是白搭。