工業物聯網核心技術(三):MQTT的安全

由於MQTT運行於TCP層之上並以明文方式傳輸,這就相當於HTTP的明文傳輸,使用Wireshark可以完全看到MQTT發送的所有消息,消息指令一覽無遺,如圖1所示。

工業物聯網核心技術(三):MQTT的安全

圖1 Wireshark抓取MQTT數據包

這樣可能會產生以下風險:

  • 設備可能會被盜用;
  • 客戶端和服務端的靜態數據可能是可訪問的(可能會被修改);
  • 協議行為可能有副作用(如計時器攻擊);
  • 拒絕服務攻擊;
  • 通信可能會被攔截、修改、重定向或者洩露;
  • 虛假控制報文注入。

作為傳輸協議,MQTT僅關注消息傳輸,提供合適的安全功能是開發者的責任。安全功能可以從三個層次來考慮——應用層、傳輸層、網絡層。

  • 應用層:在應用層上,MQTT提供了客戶標識(Client Identifier)以及用戶名和密碼,可以在應用層驗證設備。
  • 傳輸層:類似於HTTPS,MQTT基於TCP連接,也可以加上一層TLS,傳輸層使用TLS加密是確保安全的一個好手段,可以防止中間人攻擊。客戶端證書不但可以作為設備的身份憑證,還可以用來驗證設備。
  • 網絡層:如果有條件的話,可以通過拉專線或者使用VPN來連接設備與MQTT代理,以提高網絡傳輸的安全性。

認證

MQTT支持兩種層次的認證:

  • 應用層:MQTT支持客戶標識、用戶名和密碼認證;
  • 傳輸層:傳輸層可以使用TLS,除了加密通訊,還可以使用X509證書來認證設備。

客戶標識

MQTT客戶端可以發送最多65535個字符作為客戶標識(Client Identifier),一般來說可以使用嵌入式芯片的MAC地址或者芯片序列號。雖然使用客戶標識來認證可能不可靠,但是在某些封閉環境或許已經足夠了。

用戶名和密碼

MQTT協議支持通過CONNECT消息的username和password字段發送用戶名和密碼。

用戶名及密碼的認證使用起來非常方便,不過由於它們是以明文形式傳輸,所以使用抓包工具就可以輕易的獲取。

一般來說,使用客戶標識、用戶名和密碼已經足夠了,比如支持MQTT協議連接的OneNET雲平臺,就是使用了這三個字段作為認證。如果感覺還不夠安全,還可以在傳輸層進行認證。

在傳輸層認證

在傳輸層認證是這樣的:MQTT代理在TLS握手成功之後可以繼續發送客戶端的X509證書來認證設備,如果設備不合法便可以中斷連接。使用X509認證的好處是,在傳輸層就可以驗證設備的合法性,在發送CONNECT消息之前便可以阻隔非法設備的連接,以節省後續不必要的資源浪費。而且,MQTT協議運行在使用TLS時,除了提供身份認證,還可以確保消息的完整性和保密性。

選擇用戶數據格式

MQTT協議只實現了傳送消息的格式,並沒有限制用戶協議需要按照一定的風格,因此在MQTT協議之上,我們需要定義一套自己的通信協議。比如說,發佈者向設備發佈一條打開消息,設備可以回覆一個消息並攜帶返回碼,這樣的消息格式是使用二進制、字符串還是JSON格式呢?下面就簡單做個選型參考。

十六進制/二進制

MQTT原本就是基於二進制實現的,所以用戶協議使用二進制實現是一個不錯的選擇。雖然失去了直觀的可讀性,但可以將流量控制在非常小。其實對於單片機開發者來說十六進制並不陌生,因為單片機寄存器都是以位來操作的,芯片間通信也會使用十六進制/二進制。而對於沒有單片機開發經驗的工程師來說,十六進制/二進制可能就太原始了。下面我們繼續看看還有沒有其他方案。

字符串

對單片機開發者來說,字符串也是一個選擇。比如通過串口傳輸的AT指令就是基於字符串通信的。使用字符串方便了人閱讀,但是對高級語言開發者來說,字符串依舊不是最佳選擇,恐怕鍵值對(Key-Value)才是最優形式。


分享到:


相關文章: