cleanSession
is supported.will
and retain msg
are not supported.${productId}/${deviceName}/control
for subscribing${productId}/${deviceName}/event
for publishing${productId}/${deviceName}/data
for subscribing and publishing$shadow/operation/${productId}/${deviceName}
for publishing. It is distinguished by the internal type of the packet (update
or get
, corresponding to updating or pulling the device shadow document).$shadow/operation/result/${productId}/${deviceName}
for subscribing. It is distinguished by the internal type of the packet (update
, get
, or delta
). update
and get
correspond to updating and pulling the device shadow document respectively. After you modify the device shadow document through the RESTful API, the server will publish messages through this topic, whose type will be delta
at this time.$ota/report/${productID}/${deviceName}
for publishing, through which the device reports the version number and the download/upgrade progress to the cloud.$ota/update/${productID}/${deviceName}
for subscribing, through which the device receives the upgrade message from the cloud.Connection Authentication Method | Connection Domain Name and Port | Connect Message Parameters |
Certificate | MQTT server connection address. For devices in the Guangzhou region, enter ${productId}.iotcloud.tencentdevices.com , where ${productId} is a variable parameter, and you need to enter the product ID automatically generated when you create the product, such as 1A17RZR3XX.iotcloud.tencentdevices.com . Port: 8883 | KeepAlive: the time to keep the connection alive, which ranges from 0 to 900s. If IoT Hub does not receive the client's data in more than 1.5 times the KeepAlive value, it will disconnect from the client. ClientId: ${productId}${deviceName} , which is a string combination of the product ID and device name. UserName: ${productId}${deviceName};${sdkappid};${connid};${expiry} . For more information, please see the username part in the "Guide to connecting key-authenticated device" section below. PassWord: password, which can be any value. |
Key | The MQTT server connection address is the same as that for certificate authentication. Port: 1883 | KeepAlive: the time to keep the connection alive, which ranges from 0 to 900s. ClientId: ${productId}${deviceName} . UserName: ${productId}${deviceName};${sdkappid};${connid};${expiry} . For more information, please see the username part in the "Guide to connecting key-authenticated device" section below. PassWord: password. For more information, please see the password part in the "Guide to connecting key-authenticated device" section below. |
PassWord
field will not be verified when a certificate-authenticated device is connected, so you can enter any value for it during certificate authentication.KeepAlive
, ClientId
, UserName
, PassWord
, etc. (this step is not required for devices connected through the Tencent Cloud device SDK, as the SDK can automatically generate the parameters based on the device information). Then, the device uploads the authentication files to the URL (connection domain name and port) corresponding to certificate authentication, and sends an MqttConnect
message after successful authentication to complete the TCP-based MQTT connection.username
field according to the requirements of IoT Hub in the following format:The format of the `username` field is as follows:
${productId}${deviceName};${sdkappid};${connid};${expiry}
Note: `${}` indicates a variable and is not a concatenating symbol.
12010126
raw_key
.raw_key
generated in step 3 to generate a digest string for the username
with the HMACSHA1 or HMACSHA256 algorithm, which is referred to as a token.password
field according to the requirements of IoT Hub in the following format:The format of the `password` field is as follows:${token};hmac signature algorithmEnter the digest algorithm used in step 3 in the `hmac signature algorithm` field. Valid values include `hmacsha256` and `hmacsha1`.
#!/usr/bin/python# -*- coding: UTF-8 -*-import base64import hashlibimport hmacimport randomimport stringimport timeimport sys# Generate a random string of the specified lengthdef RandomConnid(length):return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))# Generate the parameters required for connection to IoT Hubdef IotHmac(productID, devicename, devicePsk):# 1. Generate `connid` as a random string to facilitate troubleshooting on the backendconnid = RandomConnid(5)# 2. Generate the expiration time of the signature, which is a UTF-8 string of the number of seconds since 00:00:00 UTC on January 1, 1970expiry = int(time.time()) + 60 * 60# 3. Generate the `clientid` part of MQTT in the format of `${productid}${devicename}`clientid = "{}{}".format(productID, devicename)# 4. Generate the `username` part of MQTT in the format of `${clientid};${sdkappid};${connid};${expiry}`username = "{};12010126;{};{}".format(clientid, connid, expiry)# 5. Sign the `username` to generate a tokensecret_key = devicePsk.encode('utf-8') # convert to bytesdata_to_sign = username.encode('utf-8') # convert to bytessecret_key = base64.b64decode(secret_key) # this is still bytestoken = hmac.new(secret_key, data_to_sign, digestmod=hashlib.sha256).hexdigest()# 6. Generate the `password` field according to the rules of IoT Hub platformpassword = "{};{}".format(token, "hmacsha256")return {"clientid" : clientid,"username" : username,"password" : password}if __name__ == '__main__':print(IotHmac(sys.argv[1], sys.argv[2], sys.argv[3]))
IotHmac.py
and run the following command. Here, replace YOUR_PRODUCTID
, YOUR_DEVICENAME
, and YOUR_PSK
with the product ID, device name, and device key of the device you actually created.python3 IotHmac.py "YOUR_PRODUCTID" "YOUR_DEVICENAME" "YOUR_PSK"
import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.*;public class IotHmac {public static void main(String[] args) throws Exception {System.out.println(IotHmac("YOUR_PRODUCTID","YOUR_DEVICENAME","YOUR_PSK"));}public static Map<String, String> IotHmac(String productID, String devicename, StringdevicePsk) throws Exception {final Base64.Decoder decoder = Base64.getDecoder();//1. Generate `connid` as a random string to facilitate troubleshooting on the backendString connid = HMACSHA256.getRandomString2(5);//2. Generate the expiration time of the signature, which is a UTF-8 string of the number of seconds since 00:00:00 UTC on January 1, 1970Long expiry = Calendar.getInstance().getTimeInMillis()/1000 +600;//3. Generate the `clientid` part of MQTT in the format of `${productid}${devicename}`String clientid = productID+devicename;//4. Generate the `username` part of MQTT in the format of `${clientid};${sdkappid};${connid};${expiry}`String username = clientid+";"+"12010126;"+connid+";"+expiry;//5. Sign the `username` to generate a token. Then, generate the `password` field according to the rules of IoT Hub platformString password = HMACSHA256.getSignature(username.getBytes(), decoder.decode(devicePsk)) + ";hmacsha256";Map<String,String> map = new HashMap<>();map.put("clientid",clientid);map.put("username",username);map.put("password",password);return map;}public static class HMACSHA256 {private static final String HMAC_SHA256 = "HmacSHA256";/*** Generate the signature data** @param data The data to be encrypted* @param key The key used for encryption* @return The generated hexadecimal string*/public static String getSignature(byte[] data, byte[] key) {try {SecretKeySpec signingKey = new SecretKeySpec(key, HMAC_SHA256);Mac mac = Mac.getInstance(HMAC_SHA256);mac.init(signingKey);byte[] rawHmac = mac.doFinal(data);return bytesToHexString(rawHmac);}catch (Exception e) {e.printStackTrace();}return null;}/*** Convert the `byte[]` array into a hexadecimal string** @param bytes The byte array to be converted* @return Converted result*/private static String bytesToHexString(byte[] bytes) {StringBuilder sb = new StringBuilder();for (int i = 0; i < bytes.length; i++) {String hex = Integer.toHexString(0xFF & bytes[i]);if (hex.length() == 1) {sb.append('0');}sb.append(hex);}return sb.toString();}public static String getRandomString2(int length) {Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(3);long result = 0;switch (number) {case 0:result = Math.round(Math.random() * 25 + 65);sb.append(String.valueOf((char) result));break;case 1:result = Math.round(Math.random() * 25 + 97);sb.append(String.valueOf((char) result));break;case 2:sb.append(String.valueOf(new Random().nextInt(10)));break;}}return sb.toString();}}}
// The following is the way to import the node. If a browser is used, use the corresponding way to import the `crypto-js` libraryconst crypto = require('crypto-js')// Function for generating random numbersconst randomString = (len) => {len = len || 32;var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';var maxPos = chars.length;var pwd = '';for (let i = 0; i < len; i++) {pwd += chars.charAt(Math.floor(Math.random() * maxPos));}return pwd;}// The product ID, device name, and device key are requiredconst productId = 'YOUR_PRODUCTID';const deviceName = 'YOUR_DEVICENAME';const devicePsk = 'YOUR_PSK';// 1. Generate `connid` as a random string to facilitate troubleshooting on the backendconst connid = randomString(5);// 2. Generate the expiration time of the signature, which is a UTF-8 string of the number of seconds since 00:00:00 UTC on January 1, 1970const expiry = Math.round(new Date().getTime() / 1000) + 3600 * 24;// 3. Generate the `clientid` part of MQTT in the format of `${productid}${devicename}`const clientId = productId + deviceName;// 4. Generate the `username` part of MQTT in the format of `${clientid};${sdkappid};${connid};${expiry}`const userName = `${clientId};12010126;${connid};${expiry}`;//5. Sign the `username` to generate a token. Then, generate the `password` field according to the rules of IoT Hub platformconst rawKey = crypto.enc.Base64.parse(devicePsk); // Base64-decode the device keyconst token = crypto.HmacSHA256(userName, rawKey);const password = token.toString(crypto.enc.Hex) + ";hmacsha256";console.log(`userName:${userName}\\npassword:${password}`);
#include "limits.h"#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include "HAL_Platform.h"#include "utils_base64.h"#include "utils_hmac.h"/* Max size of base64 encoded PSK = 64, after decode: 64/4*3 = 48*/#define DECODE_PSK_LENGTH 48/* MAX valid time when connect to MQTT server. 0: always valid *//* Use this only if the device has accurate UTC time. Otherwise, set to 0 */#define MAX_ACCESS_EXPIRE_TIMEOUT (0)/* Max size of conn Id */#define MAX_CONN_ID_LEN (6)/* IoT C-SDK APPID */#define QCLOUD_IOT_DEVICE_SDK_APPID "21****06"#define QCLOUD_IOT_DEVICE_SDK_APPID_LEN (sizeof(QCLOUD_IOT_DEVICE_SDK_APPID) - 1)static void HexDump(char *pData, uint16_t len){int i;for (i = 0; i < len; i++) {HAL_Printf("0x%02.2x ", (unsigned char)pData[i]);}HAL_Printf("\\n");}static void get_next_conn_id(char *conn_id){int i;srand((unsigned)HAL_GetTimeMs());for (i = 0; i < MAX_CONN_ID_LEN - 1; i++) {int flag = rand() % 3;switch (flag) {case 0:conn_id[i] = (rand() % 26) + 'a';break;case 1:conn_id[i] = (rand() % 26) + 'A';break;case 2:conn_id[i] = (rand() % 10) + '0';break;}}conn_id[MAX_CONN_ID_LEN - 1] = '\\0';}int main(int argc, char **argv){char *product_id = NULL;char *device_name = NULL;char *device_secret = NULL;char *username = NULL;int username_len = 0;char conn_id[MAX_CONN_ID_LEN];char password[51] = {0};char username_sign[41] = {0};char psk_base64decode[DECODE_PSK_LENGTH];size_t psk_base64decode_len = 0;long cur_timestamp = 0;if (argc != 4) {HAL_Printf("please ./qcloud-mqtt-sign product_id device_name device_secret\\r\\n");return -1;}product_id = argv[1];device_name = argv[2];device_secret = argv[3];/* first device_secret base64 decode */qcloud_iot_utils_base64decode((unsigned char *)psk_base64decode, DECODE_PSK_LENGTH, &psk_base64decode_len,(unsigned char *)device_secret, strlen(device_secret));HAL_Printf("device_secret base64 decode:");HexDump(psk_base64decode, psk_base64decode_len);/* second create mqtt username* [productdevicename;appid;randomconnid;timestamp] */cur_timestamp = HAL_Timer_current_sec() + MAX_ACCESS_EXPIRE_TIMEOUT / 1000;if (cur_timestamp <= 0 || MAX_ACCESS_EXPIRE_TIMEOUT <= 0) {cur_timestamp = LONG_MAX;}// 20 for timestampe length & delimiterusername_len = strlen(product_id) + strlen(device_name) + QCLOUD_IOT_DEVICE_SDK_APPID_LEN + MAX_CONN_ID_LEN + 20;username = (char *)HAL_Malloc(username_len);if (username == NULL) {HAL_Printf("malloc username failed!\\r\\n");return -1;}get_next_conn_id(conn_id);HAL_Snprintf(username, username_len, "%s%s;%s;%s;%ld", product_id, device_name, QCLOUD_IOT_DEVICE_SDK_APPID,conn_id, cur_timestamp);/* third use psk_base64decode hamc_sha1 calc mqtt username sign crate mqtt* password */utils_hmac_sha1(username, strlen(username), username_sign, psk_base64decode, psk_base64decode_len);HAL_Printf("username sign: %s\\r\\n", username_sign);HAL_Snprintf(password, 51, "%s;hmacsha1", username_sign);HAL_Printf("Client ID: %s%s\\r\\n", product_id, device_name);HAL_Printf("username : %s\\r\\n", username);HAL_Printf("password : %s\\r\\n", password);HAL_Free(username);return 0;}
connect
message.clientid
value in the clientid
field of the MQTT protocol.username
value in the username
field of the MQTT protocol.password
value in the password
field of the MQTT protocol and send a MqttConnect
message to the domain name and port of key authentication to connect to IoT Hub.