3. 安全通信:TLS/DTLS 在智能家居中的应用

智能家居设备,说白了就是一群“小电脑”在互相说话。但问题是——它们说的话,别人能听懂吗?

我见过太多案例:智能灯泡被隔壁小孩用手机直接控制,智能门锁的通信被截获后重放攻击。嗯,这就是没做好安全通信的后果。ETSI EN 303 645 里明确要求,设备必须使用 TLS 或 DTLS 来保护通信。今天我们就来拆解这个。

3.1 为什么是 TLS 和 DTLS?

传统 HTTP 是明文传输,就像在明信片上写密码。TLS 就是那个信封。但智能家居里,有些设备是“间歇性联网”的——比如传感器每隔几秒发一次数据,或者门锁只在开锁时通信。这时候,TCP 的握手开销就太大了。

DTLS 就是为这种情况设计的。它基于 UDP,但提供了和 TLS 同等级别的加密和认证。我个人习惯这样选型:

场景 推荐协议 原因
网关与云平台 TLS 1.2/1.3 稳定连接,双向认证
传感器上报数据 DTLS 1.2 低延迟,无连接维护
门锁/开关控制 DTLS 1.2 短消息,快速响应
固件升级 TLS 1.3 大文件传输,0-RTT
我的经验: 别盲目上 TLS 1.3。有些老芯片的硬件加速器只支持 1.2,强行上 1.3 反而导致性能下降。我在一个智能插座项目里就踩过这个坑——后来老老实实切回 1.2,吞吐量反而提升了 30%。

3.2 证书管理——最容易被忽视的环节

TLS 的核心是证书。但智能家居设备不像服务器,它们没有固定 IP,没有域名,甚至没有屏幕来显示证书信息。那怎么管理?

ETSI 标准里给出了三条路:

  1. 预置证书:出厂时烧录设备证书和 CA 根证书。
  2. 动态签发:设备首次联网时,通过注册流程向 CA 申请证书。
  3. 自签名 + 白名单:设备自签证书,云端维护设备公钥白名单。

我个人最推荐第二种。为什么?因为预置证书一旦泄露,整批设备都得召回。我在一个智能门锁项目里就遇到过——工厂烧录时证书模板被泄露,结果市面上出现了大量“克隆锁”。

避坑指南: 我曾经见过一个团队,把私钥直接写在固件里,而且是硬编码的字符串。结果固件被反编译后,私钥全网公开。记住:私钥必须存储在安全元件(SE)或 TEE 中,至少也要用芯片的 OTP 区域。

3.3 密钥存储——安全通信的最后一道防线

证书和私钥存哪里?这问题看似简单,但 90% 的安全事件都出在这里。

ETSI 标准要求:私钥必须防提取、防篡改、防侧信道攻击。具体来说:

  • 安全元件(SE):独立芯片,专门存密钥。成本高,但最安全。
  • TEE(可信执行环境):在主芯片内划出一块安全区域。性价比高。
  • 软件加密存储:用设备唯一密钥加密后存 Flash。成本最低,但风险也最高。

我建议:至少做到 TEE 级别。如果成本实在敏感,那也要用芯片自带的唯一 ID 作为密钥派生因子,绝不能直接存明文。

关键点: 密钥存储不是“存起来”就完了。还要考虑密钥轮换、吊销和销毁。ETSI 要求设备支持远程证书吊销,并且能在本地清除私钥。我在一个智能音箱项目里就实现了“自杀机制”——收到吊销指令后,直接擦除 TEE 中的密钥分区。

3.4 核心流程:TLS/DTLS 握手与证书验证

我们来看一个典型的智能家居设备与云平台建立 TLS 连接的过程。我用一个流程图来展示:

TLS/DTLS 握手与证书验证流程 TLS/DTLS 握手与证书验证流程 智能设备 家庭网关 云平台 ① ClientHello ② ServerHello + 证书链 ③ 验证证书链 ④ 预主密钥(加密) ⑤ 派生会话密钥 ⑥ ChangeCipherSpec ⑦ Finished ⑧ 加密通信(AES-GCM / ChaCha20-Poly1305) TLS 隧道 关键说明: • 设备必须验证服务器证书链,包括根CA、中间CA和服务器证书 • 证书吊销检查(CRL/OCSP)应在握手阶段完成 • 会话密钥使用前向安全(DHE/ECDHE)派生 • DTLS 增加 Cookie 机制防止 DoS 攻击

这个流程里,最容易出问题的是第③步——证书验证。很多设备只检查了证书是否过期,却没验证证书链的完整性。我见过一个智能摄像头,它只检查了服务器证书的 Common Name,结果被中间人攻击轻松绕过。

我的建议: 在设备端实现证书固定(Certificate Pinning)。把云平台的公钥哈希值硬编码在固件里,握手时比对。这样即使 CA 被攻破,攻击者也无法伪造证书。我在一个医疗健康设备项目里用了这个方法,至今没出过问题。

3.5 代码示例:ESP32 上的 TLS 客户端

我们来看一个实际代码。这是 ESP32 上使用 mbedTLS 库建立 TLS 连接的简化实现:

#include <mbedtls/net_sockets.h>
#include <mbedtls/ssl.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/x509_crt.h>

// 初始化 SSL 上下文
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;

void tls_client_init(void) {
    // 1. 加载 CA 证书
    mbedtls_x509_crt_init(&cacert);
    mbedtls_x509_crt_parse(&cacert, ca_cert_pem, strlen(ca_cert_pem) + 1);
    
    // 2. 配置 TLS
    mbedtls_ssl_config_init(&conf);
    mbedtls_ssl_config_defaults(&conf,
        MBEDTLS_SSL_IS_CLIENT,
        MBEDTLS_SSL_TRANSPORT_STREAM,
        MBEDTLS_SSL_PRESET_DEFAULT);
    
    // 3. 设置证书验证
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
    mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
    
    // 4. 设置随机数生成器
    mbedtls_entropy_init(&entropy);
    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
                         &entropy, NULL, 0);
    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
    
    // 5. 建立连接
    mbedtls_ssl_init(&ssl);
    mbedtls_ssl_setup(&ssl, &conf);
    mbedtls_ssl_set_hostname(&ssl, "cloud.smarthome.com");
    
    // 6. 握手
    int ret = mbedtls_ssl_handshake(&ssl);
    if (ret != 0) {
        // 处理握手失败
        ESP_LOGE("TLS", "Handshake failed: %d", ret);
        return;
    }
    
    // 7. 验证证书
    uint32_t flags = mbedtls_ssl_get_verify_result(&ssl);
    if (flags != 0) {
        ESP_LOGE("TLS", "Certificate verification failed: %lu", flags);
        return;
    }
    
    ESP_LOGI("TLS", "TLS connection established successfully");
}
注意: 代码中第 7 步的证书验证结果检查,很多人会忽略。我见过一个产品,把 MBEDTLS_SSL_VERIFY_REQUIRED 改成了 MBEDTLS_SSL_VERIFY_OPTIONAL,结果证书验证失败时连接依然建立。这是严重的安全漏洞。

3.6 性能优化与资源受限设备

智能家居设备很多是资源受限的——几 MB 的 Flash,几十 KB 的 RAM。TLS 握手开销不小。怎么优化?

  • 会话复用:保存 Session ID 或 Session Ticket,下次握手直接恢复。
  • PSK 模式:预共享密钥模式,省去证书交换。适合设备与网关之间。
  • 精简证书链:只保留必要的中间 CA,减少握手数据量。
  • 硬件加速:使用芯片的 AES/ECC 硬件引擎,软件实现太慢。

我在一个温控器项目里,把 TLS 握手时间从 3.2 秒降到了 0.8 秒。怎么做的?用了会话复用 + 硬件 ECC 加速。嗯,效果立竿见影。

ETSI 合规要点:
  • 必须使用 TLS 1.2 或更高版本(DTLS 1.2 或更高)
  • 必须支持双向认证(设备证书 + 服务器证书)
  • 私钥必须存储在安全硬件中
  • 必须支持证书吊销检查
  • 必须使用前向安全密码套件(ECDHE 或 DHE)

好了,安全通信这块就拆解到这里。记住:TLS/DTLS 不是装上去就完事了,证书管理和密钥存储才是真正的考验。下次你看到某个智能设备说“支持 TLS 加密”,不妨多问一句——你的私钥存哪了?