tencent cloud

DokumentasiTDMQ for MQTT

Authenticating with One-Device-One-Secret

Download
Mode fokus
Ukuran font
Terakhir diperbarui: 2026-05-12 17:20:10

Scenarios

In business scenarios with high security requirements, the business process requires each device to have a unique authentication credential, thereby ensuring the legitimacy and identity uniqueness of every device connection. Devices with limited computing power cannot use "one-device-one-certificate" based on a PKI certificate as their authentication method. Therefore, it needs an authentication method that ensures high security while consuming less CPU and memory resources.
For this reason, TDMQ for MQTT introduced the "one-device-one-secret" authentication method. Each device uses an independent Key to generate a temporary Token (MAC Token) via a shared Key for verification and server connection.

Implementation Principles

Registering a Device Identity

MQTT provides a Device Identity Registry for each instance, allowing users to configure additional settings for specific devices or clients to enable features such as "one-device-one-secret" and "propagation attributes." The Device Identity Registry exposes a set of management interfaces via CAPI to enable the creation, update, deletion, and management of device identities.

A device identity includes the following fields:
Field
Description
Remarks
DeviceID
Device ID, equivalent to Client ID
Associate device configuration with the MQTT client session.
Status
Device identity status
Ignore this configuration when the status is Disabled.
PropagatingProperties
Propagation attributes
PrimaryKey
Primary key
SecondaryKey
Secondary key
CreateTime
Device identity record creation time
-

One-Device-One-Secret


As shown in the figure above, the customer side only needs to implement the integration between the client and the Token service. TDMQ for MQTT provides a Device Identity Registry to ensure the uniqueness of the Key used by each device and the correctness of the Token. The overall steps of "one-device-one-secret" are as follows:
1. The customer-implemented Token service creates a device identity record in the MQTT Device Identity Registry using the Create Device Identity Cloud API, which contains the device's PrimaryKey and SecondaryKey. If you need to query, modify, or delete the corresponding signature Key, the corresponding Cloud API can be called.
2. The Token service uses the specified algorithm, such as Shared Access Signature Token (SAS Token) in the following Demo, to sign the Token with the returned PrimaryKey or SecondaryKey. The generated Token can also be freely composed according to actual needs.
3. Before connecting to the MQTT server, the client (device) first accesses the Token service to obtain the generated Token.
4. The client (device) passes the generated Token to the Password field to connect to the MQTT server. The Username field is not used in the "one-device-one-secret" authentication. However, it is one of the dimensions considered by the authorization policy when Data Plane Authorization Policy is enabled. For details, see Authorization Policy Description.

Token (SAS Token) Service Implementation

Here is a simple example of a Token service implementation provided by TDMQ for MQTT. In the example, the Token service has the following settings:
1. Specifies the validity period of the Token. Even if intercepted, the Token is only valid for 1 hour, significantly reducing the risk.
2. Uses the HMAC-SHA256 algorithm to generate an encrypted signature.
3. Assembles the signature from the previous step according to the specified format to generate the final Token.
The following Token service is implemented using SAS Token. Alternatively, you can implement your own Token service based on your business needs.
Java
Python
Node.js
/**
* @clientId client identifier
* @key PrimaryKey or SecondaryKey in the Device Identity Registry
*/
public static String generateSasToken(String clientId, String key) throws Exception {
// Token is valid for 3,600 seconds.
var expiry = Instant.now().getEpochSecond() + 3600;

String stringToSign = URLEncoder.encode(clientId, StandardCharsets.UTF_8) + "\\n" + expiry;
byte[] decodedKey = Base64.getDecoder().decode(key);

Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(decodedKey, "HmacSHA256");
sha256HMAC.init(secretKey);
Base64.Encoder encoder = Base64.getEncoder();

String signature = new String(encoder.encode(
sha256HMAC.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8);

String token = "SharedAccessSignature sr=" + URLEncoder.encode(clientId, StandardCharsets.UTF_8)
+ "&sig=" + URLEncoder.encode(signature, StandardCharsets.UTF_8.name()) + "&se=" + expiry;
return token;
}

from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib import parse
from hmac import HMAC

def generate_sas_token(clientId, key, expiry=3600):
ttl = time() + expiry
sign_key = "%s\\n%d" % ((parse.quote_plus(clientId)), int(ttl))
signature = b64encode(HMAC(b64decode(key), sign_key.encode('utf-8'), sha256).digest())

rawtoken = {
'sr' : clientId,
'sig': signature,
'se' : str(int(ttl))
}
return 'SharedAccessSignature ' + parse.urlencode(rawtoken)
var generateSasToken = function(clientId, key) {
resourceUri = encodeURIComponent(clientId);
// Set the Token validity period to 3,600 seconds
var expires = (Date.now() / 1000) + 3600;
expires = Math.ceil(expires);
var toSign = resourceUri + '\\n' + expires;

// Use crypto
var hmac = crypto.createHmac('sha256', Buffer.from(key, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

// Construct authorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires;
return token;
};



Bantuan dan Dukungan

Apakah halaman ini membantu?

masukan