MQTT-TLS是基于TLS协议的MQTT连接,设备和物联网平台使用发布/订阅模式的MQTT进行通信,TLS协议可以加密通信过程,确保数据的安全性。
背景信息
在进行MQTT CONNECT协议设置时,需注意:
如果同一个设备证书(ProductKey、DeviceName和DeviceSecret)或同一组ProductKey、DeviceName、ClientID、DeviceToken同时用于多个物理设备连接,可能会导致客户端频繁上线、离线。因为新设备连接认证时,原设备会被迫离线,而设备被离线后,又会自动尝试重新连接。
MQTT连接模式中,设备端Link SDK断开后会自动重连。您可以通过日志服务查看设备行为。
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+定时检测的等待时间
。超过最大超时时间未收到设备消息,服务器会自动断开连接。