3. 传输加密技术:TLS/DTLS协议配置、证书管理、加密算法选型

遥测数据在网络上跑,说白了就是裸奔。你想想看,传感器采集的温度、振动、压力数据,如果明文传输,中间人随便抓个包就能看到。我在项目里见过太多这样的案例了——客户觉得「内网安全」,结果被第三方运维人员抓了个正着。

所以,传输加密是遥测安全的第一道防线。今天我们就聊透它。

3.1 选TLS还是DTLS?先搞清楚场景

很多人一上来就问:「用TLS还是DTLS?」我的回答是:先看你的传输层用的是TCP还是UDP。

  • TLS:基于TCP,适合遥测数据量大、需要可靠传输的场景。比如工业网关上报历史数据。
  • DTLS:基于UDP,适合实时性要求高、能容忍丢包的场景。比如无人机遥测、车辆CAN总线数据流。

我个人的习惯是:能用TLS就别用DTLS。为什么?DTLS的实现坑多,尤其是重排序和丢包处理,稍不注意就握手失败。但如果你必须用UDP(比如遥测终端不支持TCP栈),那DTLS 1.2是唯一选择。

核心原则:遥测数据优先走TLS 1.3;实时流媒体或低功耗场景走DTLS 1.2。

3.2 TLS/DTLS协议配置——别用默认值

我见过太多人直接拿OpenSSL的默认配置上线。结果呢?默认支持SSLv3、TLS 1.0,一堆弱密码套件。嗯,这里要注意:遥测设备可能几年不升级固件,配置必须一次到位。

3.2.1 服务端配置(以Nginx为例)

server {
    listen 443 ssl;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
}

这里我特别强调两点:

  • 禁用TLS 1.0/1.1。遥测设备很多是嵌入式Linux,OpenSSL版本老,但至少得支持1.2。
  • 密码套件只留AES-256-GCM。别开CBC模式,Padding Oracle攻击不是闹着玩的。

3.2.2 客户端配置(以mbedTLS为例)

嵌入式设备我推荐mbedTLS,体积小、可裁剪。配置片段如下:

mbedtls_ssl_config conf;
mbedtls_ssl_config_init(&conf);
mbedtls_ssl_config_defaults(&conf,
    MBEDTLS_SSL_IS_CLIENT,
    MBEDTLS_SSL_TRANSPORT_STREAM, // TCP用STREAM,UDP用DATAGRAM
    MBEDTLS_SSL_PRESET_DEFAULT);
mbedtls_ssl_conf_min_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // TLS 1.2
mbedtls_ssl_conf_ciphersuites(&conf, ciphersuite_list); // 只包含AES-256-GCM套件

避坑指南:我曾经在STM32上移植mbedTLS,默认堆栈大小只有4KB,TLS握手直接栈溢出。建议把MBEDTLS_SSL_IN_CONTENT_LEN设为4096,栈空间至少给8KB。

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

证书管理是遥测安全里最脏最累的活。我见过一个项目,所有设备用同一个自签名证书,私钥硬编码在固件里。结果一台设备被逆向,整个网络沦陷。

3.3.1 证书体系选型

方案 适用场景 管理成本 安全性
自签名证书 原型验证、内网测试 低 低(无法吊销)
私有CA 企业级遥测网络 中 高(可吊销、可轮换)
公有CA 公网遥测平台 高 最高(浏览器信任)

我个人强烈建议:遥测网络用私有CA。你搭建一个离线CA服务器,给每台设备签发独立证书。这样即使某台设备被攻破,吊销它的证书就行,不影响其他设备。

3.3.2 证书生命周期管理

证书会过期,这是常识。但遥测设备部署在无人值守的机房里,过期了谁去换?

  • 证书有效期:建议设3年,别设10年。时间越长,私钥泄露风险越大。
  • 自动续签:用ACME协议(比如Certbot)自动续签。但嵌入式设备不支持ACME?那就预置多个证书,按时间切换。
  • 吊销列表:CRL或OCSP必须实现。我见过一个项目,证书被吊销了,但设备不检查CRL,照样能连服务器。

警告:千万不要把私钥硬编码在固件里!正确的做法是:设备首次启动时,通过安全通道(比如预置的根证书)向CA申请证书,私钥保存在安全元件(SE)或TPM中。

3.4 加密算法选型——为什么是AES-256-GCM?

选加密算法,说白了就是三个维度:安全性、性能、硬件支持。

3.4.1 算法对比

算法 密钥长度 模式 认证 硬件加速 推荐度
AES-256-GCM 256 bit GCM(伽罗瓦计数器模式) 内置GMAC ARMv8、x86 AES-NI ★★★★★
AES-256-CBC 256 bit CBC(密码分组链接) 需额外HMAC 同上 ★★☆☆☆
ChaCha20-Poly1305 256 bit 流密码 内置Poly1305 软件实现快 ★★★★☆

为什么我首选AES-256-GCM?三个理由:

  • 认证加密一体:GCM模式同时提供加密和完整性校验,不需要额外算HMAC,省CPU。
  • 硬件加速普及:现在的ARM Cortex-A系列、x86处理器基本都有AES-NI指令集,加解密速度能到Gbps级别。
  • 抗时序攻击:GCM是CTR模式变种,没有CBC的Padding Oracle问题。

但注意:GCM的nonce(初始向量)绝对不能重复。一旦nonce重用,攻击者可以直接恢复密钥流。我在项目中遇到过开发人员用固定nonce,结果被安全审计直接打回。

我的做法:nonce用「设备ID + 时间戳 + 计数器」组合生成,保证全局唯一。每次发送遥测数据前,先递增计数器,再加密。

3.5 知识体系总览

下面这张图是我梳理的传输加密技术决策流程,你照着走基本不会出错:

传输加密技术决策流程 传输加密技术选型与配置流程 传输层协议 TCP → 选TLS 1.3 UDP → 选DTLS 1.2 密码套件:AES-256-GCM + ECDHE 证书管理:私有CA + 独立证书 上线验证:抓包确认加密 + 证书链 ⚠️ 别忘了检查 nonce唯一性

3.6 实战检查清单

最后,我分享一份自己项目里用的检查清单。每次上线前,逐条过一遍:

  1. 协议版本:是否只启用了TLS 1.2/1.3或DTLS 1.2?
  2. 密码套件:是否只包含AES-256-GCM套件?是否禁用了CBC、RC4、3DES?
  3. 证书链:设备是否验证了服务器证书的完整链?是否检查了根证书指纹?
  4. 私钥保护:私钥是否存储在安全元件中?是否设置了访问权限?
  5. nonce管理:GCM的nonce是否全局唯一?是否实现了计数器持久化?
  6. 会话复用:是否启用了会话缓存?缓存超时是否合理(建议10分钟)?
  7. 降级攻击:是否禁用了版本降级和密码套件降级?

最后一句提醒:我曾经在验收测试时,用Wireshark抓包发现设备协商到了TLS 1.0。查了半天,原来是OpenSSL编译时没禁用旧版本。所以,编译配置和运行时配置要双重检查。