MQTT-TLS是基於TLS協議的MQTT串連,裝置和物聯網平台使用發布/訂閱模式的MQTT進行通訊,TLS協議可以加密通訊過程,確保資料的安全性。
背景資訊
在進行MQTT CONNECT通訊協定設定時,需注意:
如果同一個裝置認證(ProductKey、DeviceName和DeviceSecret)或同一組ProductKey、DeviceName、ClientID、DeviceToken同時用於多個物理裝置串連,可能會導致用戶端頻繁上線、離線。因為新裝置串連認證時,原裝置會被迫離線,而裝置被離線後,又會自動嘗試重新串連。
MQTT串連模式中,裝置端Link SDK斷開後會自動重連。您可以通過Log Service查看裝置行為。
MQTT用戶端直連
裝置使用TCP接入的安全風險非常高,建立的企業版執行個體預設關閉TCP(非TLS加密)接入方式。
為保障通訊安全,需使用TLS加密的串連方式。
裝置端Link SDK已配置TLS加密,您無需自行配置。
若您自行開發裝置端,需要使用根憑證完成對物聯網平台的鑒權。目前有兩套根憑證:
推薦: 阿里雲物聯網平台自我簽署憑證,該CA根憑證有效期間到2053年07月04日,串連8883連接埠。
重要您可以使用MD5:
c7a6afb466713832af778a7bcb6d1aef
校正認證檔案,確保認證檔案的完整性和正確性。Global Sign R1根憑證,該CA根憑證有效期間到2028年01月28日,串連1883連接埠。認證失效後將無法再用於校正伺服器。因此,請確保所有使用TLS加密的裝置,均具備更新CA根憑證的功能。
使用MQTT用戶端串連伺服器。
串連方式,請參見開源MQTT用戶端。 MQTT協議的更多資訊,請參見 MQTT官方文檔 。
說明若使用第三方代碼,阿里雲不提供支援人員。
MQTT串連時的參數說明。建議您使用裝置端SDK接入物聯網平台,以C語言為例,請參見MQTT接入。如果您自行開發接入,串連參數如下。
參數
說明
接入網域名稱
公用執行個體和企業版執行個體中,MQTT的接入網域名稱,請參見查看和配置執行個體終端節點資訊(Endpoint)。
可變前序(variable header):Keep Alive
CONNECT指令中需包含Keep Alive(保活時間)。保活心跳時間取值範圍為30秒~1200秒,建議取值300秒以上。若網路不穩定,請將心跳時間設定長一些。如果心跳時間不在保活時間內,物聯網平台會拒絕串連。
更多說明,請參見下文MQTT保活。
MQTT的CONNECT報文參數
一機一密、一型一密預註冊認證方式:使用裝置認證(ProductKey、DeviceName和DeviceSecret)串連。
mqttClientId: clientId+"|securemode=3,signmethod=hmacsha1,timestamp=132323232|" mqttUsername: deviceName+"&"+productKey mqttPassword: sign_hmac(deviceSecret,content)
mqttClientId:格式中
| |
內為擴充參數。clientId:表示用戶端ID,可自訂,長度不可超過64個字元。建議使用裝置的MAC地址或SN碼,方便您識別區分不同的用戶端。
securemode:表示目前安全模式,可選值有2(TLS直連模式)和3(TCP直連模式)。
signmethod:表示簽名演算法類型。支援hmacmd5,hmacsha1和hmacsha256。
timestamp:表示目前時間毫秒值,可以不傳遞。
mqttPassword:sign簽名需把提交給伺服器的參數按字典排序後,根據signmethod加簽。簽名計算樣本,請參見MQTT串連簽名樣本。
content的值為提交給伺服器的參數(productKey、deviceName、timestamp和clientId),按照參數名稱首字母字典排序, 然後將參數值依次拼接。
重要此處productKey和deviceName為必填參數,timestamp和clientId為選擇性參數。若傳入timestamp或clientId,必須與mqttClientId中的設定相同。
樣本:
假設
clientId = 12345,deviceName = device, productKey = pk, timestamp = 789,signmethod=hmacsha1,deviceSecret=secret
,那麼使用TCP方式提交給MQTT的參數如下:mqttclientId=12345|securemode=3,signmethod=hmacsha1,timestamp=789| mqttUsername=device&pk mqttPassword=hmacsha1("secret","clientId12345deviceNamedeviceproductKeypktimestamp789").toHexString();
加密後的Password為二進位轉16制字串,樣本結果為:
FAFD82A3D602B37FB0FA8B7892F24A477F85****
MQTT簽名參數計算方法,請參見如何計算MQTT簽名參數。
一型一密免預註冊認證方式:使用ProductKey、DeviceName、ClientID、DeviceToken串連。
mqttClientId: clientId+"|securemode=-2,authType=connwl|" mqttUsername: deviceName+"&"+productKey mqttPassword: deviceToken
mqttClientId:格式中
| |
內為擴充參數。clientId、deviceToken:裝置動態註冊時獲得的ClientID、DeviceToken,請參見基於MQTT協議的裝置動態註冊。
securemode:表示目前安全模式,採用一型一密免預註冊時,固定取值為-2。
authType:表示認證方式,採用一型一密免預註冊時,固定取值為connwl。
使用樣本
使用開源MQTT用戶端接入物聯網平台的樣本,請參見:
MQTT保活
裝置端在保活時間間隔內,至少需要發送一次報文,包括ping請求。
串連保活時間的取值範圍為30秒~1200秒。建議取值300秒以上。
從物聯網平台發送CONNACK響應CONNECT訊息時,開始心跳計時。收到PUBLISH、SUBSCRIBE、PING或 PUBACK訊息時,會重設計時器。物聯網平台每隔30秒定時檢測一次裝置的保活心跳,裝置上線時間點距離最新定時檢測時間點的時間,是定時檢測的等待時間。定義最大逾時時間為:保活心跳時間*1.5+定時檢測的等待時間
。超過最大逾時時間未收到裝置訊息,伺服器會自動中斷連線。