Tous les produits
Search
Centre de documentation

IoT Platform:Enregistrement dynamique avec certificat unique par produit via MQTT

Dernière mise à jour :Aug 09, 2026

Exemple Java illustrant comment réaliser un unique-certificate-per-product dynamic registration via MQTT afin d'obtenir le DeviceSecret pour l'authentification sur IoT Platform.

Prérequis

Vous avez suivi les étapes décrites dans la documentation relative au certificat unique par produit :

  1. Créez un produit.

  2. Activez l'enregistrement dynamique.

  3. (Avec pré-enregistrement uniquement) Ajoutez un appareil.

  4. Gravez les informations de l'appareil sur la ligne de production.

Contexte

IoT Platform prend en charge plusieurs méthodes d'authentification des appareils. Pour plus d'informations, consultez la section Authentification des appareils.

IoT Platform permet l'utilisation du dynamic registration via MQTT pour les appareils pré-enregistrés et ceux sans enregistrement préalable, en utilisant la méthode unique-certificate-per-product. Pour obtenir des détails sur le processus et les paramètres, reportez-vous à la rubrique Enregistrement dynamique des appareils via MQTT.

Préparation de l'environnement de développement

Environnement de développement :

Procédure

  1. Ouvrez IntelliJ IDEA et créez un projet Maven. Pour cet exemple, nommez le projet MqttDynamicRegistration.

  2. Dans le fichier pom.xml du projet, ajoutez les dépendances Maven suivantes, puis cliquez sur l'icône Load Maven Changes pour les télécharger.

    <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.83</version>
    </dependency>
  3. Dans le répertoire /src/main/java du projet MqttDynamicRegistration, créez une classe Java nommée DynamicRegisterByMqtt et ajoutez le code suivant.

    Remarque
    • Si un device n'est pas activé, vous pouvez effectuer plusieurs fois le dynamic registration. Le DeviceSecret issu du dernier enregistrement est celui qui s'applique. Veillez à ce que le dernier DeviceSecret soit persisté sur l'device.

    • Si un device est déjà activé, vous devez appeler l'opération API ResetThing pour réinitialiser son statut de dynamic registration à « non enregistré » dans le cloud avant de pouvoir réenregistrer l'device.

    import java.nio.charset.StandardCharsets;
    import java.util.Random;
    import java.util.Set;
    import java.util.SortedMap;
    import java.util.TreeMap;
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
    import org.eclipse.paho.client.mqttv3.MqttCallback;
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    import com.alibaba.fastjson.JSONObject;
    /**
     * Performs dynamic registration for a device. 
     */
    public class DynamicRegisterByMqtt {
        // The region ID where your product is located.
        private static String regionId = "cn-shanghai";
        // The encryption method. The available MAC algorithms are HmacMD5, HmacSHA1, and HmacSHA256. The value must be consistent with the signmethod parameter.
        private static final String HMAC_ALGORITHM = "hmacsha1";
        // The topic for receiving the device certificate from IoT Platform. You can use this topic directly without creating or subscribing to it.
        private static final String REGISTER_TOPIC = "/ext/register";
        /**
         * Performs dynamic registration.
         * 
         * @param productKey The ProductKey of the product.
         * @param productSecret The ProductSecret of the product.
         * @param deviceName The name of the device.
         * @throws Exception
         */
        public void register(String productKey, String productSecret, String deviceName) throws Exception {
            // The endpoint. You must use Transport Layer Security (TLS).
            String broker = "ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
            // The client ID. We recommend that you use the device's MAC address or serial number (SN). The client ID must be within 64 characters.
            String clientId = productKey + "." + deviceName;
            // Obtains a random value.
            Random r = new Random();
            int random = r.nextInt(1000000);
            // The securemode parameter can only be set to 2, which indicates that only TLS can be used. The signmethod parameter specifies the signature algorithm.
            String clientOpts = "|securemode=2,authType=register,signmethod=" + HMAC_ALGORITHM + ",random=" + random + "|";
            // The MQTT client ID for connection.
            String mqttClientId = clientId + clientOpts;
            // The MQTT username for connection.
            String mqttUsername = deviceName + "&" + productKey;
            // The MQTT password for connection, which is the signature.
            JSONObject params = new JSONObject();
            params.put("productKey", productKey);
            params.put("deviceName", deviceName);
            params.put("random", random);
            String mqttPassword = sign(params, productSecret);
            // Perform dynamic registration through an MQTT CONNECT message.
            connect(broker, mqttClientId, mqttUsername, mqttPassword);
        }
        /**
         * Sends dynamic registration information through an MQTT CONNECT message.
         * 
         * @param serverURL The endpoint for dynamic registration.
         * @param clientId The client ID.
         * @param username The MQTT username.
         * @param password The MQTT password.
         */
        @SuppressWarnings("resource")
        private void connect(String serverURL, String clientId, String username, String password) {
            try {
                MemoryPersistence persistence = new MemoryPersistence();
                MqttClient sampleClient = new MqttClient(serverURL, clientId, persistence);
                MqttConnectOptions connOpts = new MqttConnectOptions();
                connOpts.setMqttVersion(4); // Use MQTT 3.1.1.
                connOpts.setUserName(username); // The username.
                connOpts.setPassword(password.toCharArray()); // The password.
                connOpts.setAutomaticReconnect(false); // The MQTT dynamic registration protocol requires disabling automatic reconnection.
                System.out.println("----- register params -----");
                System.out.print("server=" + serverURL + ",clientId=" + clientId);
                System.out.println(",username=" + username + ",password=" + password);
                sampleClient.setCallback(new MqttCallback() {
                    @Override
                    public void messageArrived(String topic, MqttMessage message) throws Exception {
                        // Process only the response for dynamic registration.
                        if (REGISTER_TOPIC.equals(topic)) {
                            String payload = new String(message.getPayload(), StandardCharsets.UTF_8);
                            System.out.println("----- register result -----");
                            System.out.println(payload);
                            sampleClient.disconnect();
                        }
                    }
                    @Override
                    public void deliveryComplete(IMqttDeliveryToken token) {
                    }
                    @Override
                    public void connectionLost(Throwable cause) {
                    }
                });
                sampleClient.connect(connOpts);
            } catch (MqttException e) {
                System.out.print("register failed: clientId=" + clientId);
                System.out.println(",username=" + username + ",password=" + password);
                System.out.println("reason " + e.getReasonCode());
                System.out.println("msg " + e.getMessage());
                System.out.println("loc " + e.getLocalizedMessage());
                System.out.println("cause " + e.getCause());
                System.out.println("except " + e);
                e.printStackTrace();
            }
        }
        /**
         * Generates a signature for dynamic registration.
         * 
         * @param params The parameters used for the signature.
         * @param productSecret The ProductSecret of the product.
         * @return The signature as a hexadecimal string.
         */
        private String sign(JSONObject params, String productSecret) {
            // Sorts the request parameters in alphabetical order.
            Set<String> keys = getSortedKeys(params);
            // Excludes the 'sign' and 'signMethod' parameters.
            keys.remove("sign");
            keys.remove("signMethod");
            // Assembles the plaintext for the signature.
            StringBuffer content = new StringBuffer();
            for (String key : keys) {
                content.append(key);
                content.append(params.getString(key));
            }
            // Calculates the signature.
            String sign = encrypt(content.toString(), productSecret);
            System.out.println("sign content=" + content);
            System.out.println("sign result=" + sign);
            return sign;
        }
        /**
         * Gets the sorted set of keys from a JSON object.
         *
         * @param json The JSON object to sort.
         * @return The sorted set of keys.
         */
        private Set<String> getSortedKeys(JSONObject json) {
            SortedMap<String, String> map = new TreeMap<String, String>();
            for (String key : json.keySet()) {
                String value = json.getString(key);
                map.put(key, value);
            }
            return map.keySet();
        }
        /**
         * Encrypts content by using the HMAC_ALGORITHM.
         * 
         * @param content The plaintext.
         * @param secret The key.
         * @return The ciphertext.
         */
        private String encrypt(String content, String secret) {
            try {
                byte[] text = content.getBytes(StandardCharsets.UTF_8);
                byte[] key = secret.getBytes(StandardCharsets.UTF_8);
                SecretKeySpec secretKey = new SecretKeySpec(key, HMAC_ALGORITHM);
                Mac mac = Mac.getInstance(secretKey.getAlgorithm());
                mac.init(secretKey);
                return byte2hex(mac.doFinal(text));
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        /**
         * Converts a byte array to a hexadecimal string.
         * 
         * @param b The byte array.
         * @return The hexadecimal string.
         */
        private String byte2hex(byte[] b) {
            StringBuffer sb = new StringBuffer();
            for (int n = 0; b != null && n < b.length; n++) {
                String stmp = Integer.toHexString(b[n] & 0XFF);
                if (stmp.length() == 1) {
                    sb.append('0');
                }
                sb.append(stmp);
            }
            return sb.toString().toUpperCase();
        }
        public static void main(String[] args) throws Exception {
            String productKey = "a1IoK******";
            String productSecret = "6vEu5Qlj5S******";
            String deviceName = "OvenDevice01";
            // Perform dynamic registration.
            DynamicRegisterByMqtt client = new DynamicRegisterByMqtt();
            client.register(productKey, productSecret, deviceName);
            // After dynamic registration, the DeviceSecret must be persisted locally on the device.
        }
    }
  4. Configurez les paramètres du code avec les informations réelles de votre device.

    Paramètre Exemple Description
    regionId cn-shanghai L'region ID de votre instance IoT Platform. Pour consulter la liste des codes de région, reportez-vous à la section Liste des régions.
    productKey a1IoK La ProductKey du product, qui a été gravée sur l'device. Connectez-vous à la console IoT Platform et consultez la ProductKey sur la page Product Details.
    productSecret 6vEu5Qlj5S La ProductSecret du product, qui a été gravée sur l'device. Connectez-vous à la console IoT Platform et consultez la ProductSecret sur la page Product Details.
    deviceName OvenDevice01

    Le nom de votre device.

    IoT Platform vérifie le DeviceName lors de l'activation de l'device. Nous vous recommandons d'utiliser un identifiant directement lisible depuis l'device, tel que son adresse MAC, son IMEI (International Mobile Equipment Identity) ou son numéro de série (SN), comme DeviceName.

    broker "ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883"

    L'endpoint pour le dynamic registration de l'device. Le format est ssl://" + "${YourInstanceDomain}" + ":" +1883.

    Dans ce format, ${YourInstanceDomain} correspond à l'endpoint MQTT. Pour savoir comment obtenir l'endpoint MQTT, consultez la rubrique Afficher et configurer les endpoints d'instance.

  5. Exécutez le fichier DynamicRegisterByMqtt.java. L'device envoie une demande d'authentification au cloud contenant le DeviceName, la ProductKey de son product et la ProductSecret.

    Après validation de la demande par IoT Platform, l'device reçoit le DeviceSecret (par exemple, 8d1f0cdab49dd229cf3b75****) depuis le cloud.

    sign content=deviceNameOvenDevice01productKeyaIIoxxxrandom462
    sign result=A76A60CEDBA4899D304320A58E8719D75xxx
    ----- register params -----
    server=ssl://aIIoxxx.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883,clientId=aIIoxxx.OvenDevice01|securemode=2,authType=register,signmethod=hmacsha1,random=462335|,username=OvenDevice01&aIIoxxx,password=A76A60CE
    ----- register result -----
    {"deviceSecret":"8d1f0cdab49dd229cf3b75xxx","productKey":"aIIoxxx","deviceName":"OvenDevice01"}
    Process finished with exit code 0

Étapes suivantes

Une fois que l'device a obtenu le device certificate (ProductKey, DeviceName et DeviceSecret), utilisez un client MQTT pour le connecter à IoT Platform afin d'échanger des données.

Pour plus d'informations, consultez l'exemple de connexion Paho MQTT Java.