All Products
Search
Document Center

IoT Platform:Pendaftaran dinamis per produk dengan sertifikat unik melalui MQTT

Last Updated:Jun 17, 2026

Contoh Java yang menunjukkan cara melakukan unique-certificate-per-product dynamic registration melalui MQTT untuk memperoleh DeviceSecret guna autentikasi pada IoT Platform.

Prasyarat

Anda telah menyelesaikan langkah-langkah berikut yang dijelaskan dalam dokumentasi unique-certificate-per-product:

  1. Buat produk.

  2. Aktifkan pendaftaran dinamis.

  3. (Hanya untuk pra-pendaftaran) Tambahkan perangkat.

  4. Unggah informasi perangkat di garis produksi.

Informasi latar belakang

IoT Platform mendukung beberapa metode autentikasi perangkat. Untuk informasi selengkapnya, lihat Device authentication.

IoT Platform mendukung dynamic registration melalui MQTT baik untuk perangkat yang telah dipra-daftarkan maupun perangkat tanpa pendaftaran sebelumnya menggunakan metode unique-certificate-per-product. Untuk detail proses dan parameter, lihat Dynamic device registration over MQTT.

Siapkan lingkungan pengembangan

Lingkungan pengembangan:

Prosedur

  1. Buka IntelliJ IDEA dan buat proyek Maven. Untuk contoh ini, beri nama proyek MqttDynamicRegistration.
  2. Pada file pom.xml proyek, tambahkan dependensi Maven berikut, lalu klik ikon Load Maven Changes untuk mengunduhnya.
    <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. Pada direktori /src/main/java proyek MqttDynamicRegistration, buat kelas Java bernama DynamicRegisterByMqtt dan tambahkan kode berikut.
    Catatan
    • Jika suatu device belum diaktifkan, Anda dapat melakukan dynamic registration beberapa kali. DeviceSecret dari pendaftaran terbaru yang berlaku. Pastikan DeviceSecret terbaru dipersistensikan ke dalam device.
    • Jika suatu device sudah diaktifkan, Anda harus memanggil operasi API ResetThing untuk mengatur ulang status dynamic registration-nya menjadi belum terdaftar di cloud sebelum dapat mendaftarkan ulang device tersebut.
    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;
    /**
     * Melakukan pendaftaran dinamis untuk perangkat. 
     */
    public class DynamicRegisterByMqtt {
        // ID wilayah tempat produk Anda berada.
        private static String regionId = "cn-shanghai";
        // Metode enkripsi. Algoritma MAC yang tersedia adalah HmacMD5, HmacSHA1, dan HmacSHA256. Nilainya harus konsisten dengan parameter signmethod.
        private static final String HMAC_ALGORITHM = "hmacsha1";
        // Topik untuk menerima sertifikat perangkat dari IoT Platform. Anda dapat langsung menggunakan topik ini tanpa membuat atau berlangganan.
        private static final String REGISTER_TOPIC = "/ext/register";
        /**
         * Melakukan pendaftaran dinamis.
         * 
         * @param productKey ProductKey produk.
         * @param productSecret ProductSecret produk.
         * @param deviceName Nama perangkat.
         * @throws Exception
         */
        public void register(String productKey, String productSecret, String deviceName) throws Exception {
            // Titik akhir. Anda harus menggunakan Transport Layer Security (TLS).
            String broker = "ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
            // ID klien. Disarankan menggunakan alamat MAC atau nomor seri (SN) perangkat. ID klien harus tidak lebih dari 64 karakter.
            String clientId = productKey + "." + deviceName;
            // Mendapatkan nilai acak.
            Random r = new Random();
            int random = r.nextInt(1000000);
            // Parameter securemode hanya dapat diatur ke 2, yang menunjukkan bahwa hanya TLS yang digunakan. Parameter signmethod menentukan algoritma signature.
            String clientOpts = "|securemode=2,authType=register,signmethod=" + HMAC_ALGORITHM + ",random=" + random + "|";
            // ID klien MQTT untuk koneksi.
            String mqttClientId = clientId + clientOpts;
            // Username MQTT untuk koneksi.
            String mqttUsername = deviceName + "&" + productKey;
            // Password MQTT untuk koneksi, yaitu signature.
            JSONObject params = new JSONObject();
            params.put("productKey", productKey);
            params.put("deviceName", deviceName);
            params.put("random", random);
            String mqttPassword = sign(params, productSecret);
            // Lakukan pendaftaran dinamis melalui pesan MQTT CONNECT.
            connect(broker, mqttClientId, mqttUsername, mqttPassword);
        }
        /**
         * Mengirimkan informasi pendaftaran dinamis melalui pesan MQTT CONNECT.
         * 
         * @param serverURL Titik akhir untuk pendaftaran dinamis.
         * @param clientId ID klien.
         * @param username Username MQTT.
         * @param password Password MQTT.
         */
        @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); // Gunakan MQTT 3.1.1.
                connOpts.setUserName(username); // Username.
                connOpts.setPassword(password.toCharArray()); // Password.
                connOpts.setAutomaticReconnect(false); // Protokol pendaftaran dinamis MQTT mengharuskan nonaktifkan koneksi ulang otomatis.
                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 {
                        // Proses hanya respons untuk pendaftaran dinamis.
                        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();
            }
        }
        /**
         * Menghasilkan signature untuk pendaftaran dinamis.
         * 
         * @param params Parameter yang digunakan untuk signature.
         * @param productSecret ProductSecret produk.
         * @return Signature dalam bentuk string heksadesimal.
         */
        private String sign(JSONObject params, String productSecret) {
            // Mengurutkan parameter permintaan secara alfabetis.
            Set<String> keys = getSortedKeys(params);
            // Kecualikan parameter 'sign' dan 'signMethod'.
            keys.remove("sign");
            keys.remove("signMethod");
            // Menyusun teks biasa untuk signature.
            StringBuffer content = new StringBuffer();
            for (String key : keys) {
                content.append(key);
                content.append(params.getString(key));
            }
            // Menghitung signature.
            String sign = encrypt(content.toString(), productSecret);
            System.out.println("sign content=" + content);
            System.out.println("sign result=" + sign);
            return sign;
        }
        /**
         * Mendapatkan set terurut kunci dari objek JSON.
         *
         * @param json Objek JSON yang akan diurutkan.
         * @return Set terurut kunci.
         */
        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();
        }
        /**
         * Mengenkripsi konten menggunakan HMAC_ALGORITHM.
         * 
         * @param content Teks biasa.
         * @param secret Kunci.
         * @return Teks terenkripsi.
         */
        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;
            }
        }
        /**
         * Mengonversi array byte menjadi string heksadesimal.
         * 
         * @param b Array byte.
         * @return String heksadesimal.
         */
        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";
            // Lakukan pendaftaran dinamis.
            DynamicRegisterByMqtt client = new DynamicRegisterByMqtt();
            client.register(productKey, productSecret, deviceName);
            // Setelah pendaftaran dinamis, DeviceSecret harus dipersistensikan secara lokal pada perangkat.
        }
    }
  4. Konfigurasikan parameter dalam kode dengan informasi device aktual Anda.
    Parameter Contoh Deskripsi
    regionId cn-shanghai region ID dari instans IoT Platform Anda. Untuk daftar kode wilayah, lihat Region list.
    productKey a1IoK****** ProductKey dari product, yang telah dibakar ke dalam device. Anda dapat masuk ke IoT Platform console dan melihat ProductKey pada halaman Product Details.
    productSecret 6vEu5Qlj5S****** ProductSecret dari product, yang telah dibakar ke dalam device. Anda dapat masuk ke IoT Platform console dan melihat ProductSecret pada halaman Product Details.
    deviceName OvenDevice01 Nama device Anda.

    IoT Platform memverifikasi DeviceName selama aktivasi device. Disarankan menggunakan pengenal yang dapat langsung dibaca dari device, seperti alamat MAC, International Mobile Equipment Identity (IMEI), atau nomor seri (SN), sebagai DeviceName.

    broker "ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883" endpoint untuk dynamic registration device. Formatnya adalah ssl://" + "${YourInstanceDomain}" + ":" +1883.

    Dalam format ini, ${YourInstanceDomain} adalah endpoint MQTT. Untuk informasi cara memperoleh endpoint MQTT, lihat View and configure instance endpoints.

  5. Jalankan file DynamicRegisterByMqtt.java. device mengirimkan permintaan autentikasi ke cloud yang berisi DeviceName, ProductKey dari product-nya, dan ProductSecret.

    Setelah IoT Platform memverifikasi permintaan tersebut, device menerima DeviceSecret (misalnya, 8d1f0cdab49dd229cf3b75****) dari 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

Langkah selanjutnya

Setelah device memperoleh device certificate (ProductKey, DeviceName, dan DeviceSecret), gunakan klien MQTT untuk menghubungkannya ke IoT Platform guna komunikasi data.

Untuk informasi selengkapnya, lihat Paho MQTT Java connection example.