全部产品
Search
文档中心

IoT Platform:Pendaftaran dinamis berbasis MQTT

更新时间:Jul 06, 2025

Topik ini menjelaskan cara mendaftarkan perangkat secara dinamis menggunakan protokol Message Queuing Telemetry Transport (MQTT) dan mendapatkan DeviceSecrets. DeviceSecrets diperlukan untuk otentikasi saat menghubungkan perangkat ke IoT Platform. Dalam topik ini, kode Java contoh digunakan untuk pre-registrasi otentikasi sertifikat-tunggal-per-produk.

Prasyarat

Langkah-langkah berikut yang dijelaskan dalam topik Verifikasi Sertifikat-Tunggal-Per-Produk telah dilakukan:

  1. Buat produk.

  2. Aktifkan pendaftaran dinamis.

  3. Tambahkan perangkat.

  4. Instal sertifikat perangkat pada perangkat.

Informasi latar belakang

IoT Platform mendukung beberapa metode otentikasi untuk perangkat. Untuk informasi lebih lanjut, lihat Otentikasi Perangkat.

Anda dapat membuat koneksi MQTT untuk melakukan pre-registrasi otentikasi sertifikat-tunggal-per-produk atau otentikasi sertifikat-tunggal-per-produk tanpa pre-registrasi. Untuk informasi lebih lanjut tentang prosedur dan parameter pendaftaran dinamis berbasis MQTT, lihat Pendaftaran Dinamis Berbasis MQTT.

Siapkan lingkungan pengembangan

Dalam contoh ini, lingkungan pengembangan terdiri dari komponen-komponen berikut:

Prosedur

  1. Buka IntelliJ IDEA dan buat proyek Maven. Dalam contoh ini, proyek MQTT dynamic registration dibuat.
  2. Di file pom.xml, tambahkan dependensi Maven berikut dan klik Load Maven Changes untuk mengunduh paket-paket tersebut.
    <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. Temukan proyek MQTT dynamic registration dan buat kelas Java di direktori \src\main\java proyek. Dalam contoh ini, kelas DynamicRegisterByMqtt dibuat. Masukkan kode berikut.
    Catatan
    • Jika perangkat belum diaktifkan, Anda dapat melakukan pendaftaran dinamis beberapa kali. Namun, hanya DeviceSecret terbaru yang valid. Pastikan bahwa DeviceSecret terbaru telah di-burn pada perangkat.
    • Jika perangkat telah diaktifkan, Anda harus memanggil operasi ResetThing untuk menyetel ulang status pendaftaran perangkat menjadi tidak terdaftar di konsol IoT Platform. Kemudian, Anda dapat mendaftarkan perangkat secara dinamis.
    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";
    
        // Tentukan algoritma enkripsi. Nilai valid: hmacmd5, hmacsha1, dan hmacsha256. Nilai yang Anda tentukan harus sama dengan nilai parameter signmethod.
        private static final String HMAC_ALGORITHM = "hmacsha1";
    
        // Topik yang menerima sertifikat perangkat dari IoT Platform. Anda dapat langsung menggunakan topik tanpa perlu membuat atau berlangganan topik.
        private static final String REGISTER_TOPIC = "/ext/register";
    
        /**
         * Pendaftaran dinamis.
         *
         * @param productKey: ProductKey dari produk tempat perangkat milik.
         * @param productSecret: ProductSecret dari produk tempat perangkat milik.
         * @param deviceName: DeviceName dari perangkat.
         * @throws Exception
         */
        public void register(String productKey, String productSecret, String deviceName) throws Exception {
    
            // Endpoint layanan otentikasi. Anda harus menggunakan protokol Transport Layer Security (TLS).
            String broker = "ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
    
            // ID klien. Kami sarankan Anda menggunakan alamat media access control (MAC) atau nomor seri (SN) perangkat. ID klien bisa maksimal 64 karakter panjangnya.
            String clientId = productKey + "." + deviceName;
    
            // Dapatkan nilai acak.
            Random r = new Random();
            int random = r.nextInt(1000000);
    
            // Setel nilai parameter securemode ke 2. Anda tidak dapat mengubah nilai tersebut. Nilai 2 menentukan bahwa TLS digunakan. Parameter signmethod menentukan algoritma enkripsi.
            String clientOpts = "|securemode=2,authType=register,signmethod=" + HMAC_ALGORITHM + ",random=" + random + "|";
    
            // ID klien MQTT.
            String mqttClientId = clientId + clientOpts;
    
            // Nama pengguna klien MQTT.
            String mqttUsername = deviceName + "&" + productKey;
    
            // Tanda tangan yang digunakan oleh klien MQTT untuk terhubung ke IoT Platform.
            JSONObject params = new JSONObject();
            params.put("productKey", productKey);
            params.put("deviceName", deviceName);
            params.put("random", random);
            String mqttPassword = sign(params, productSecret);
    
            // Kirim pesan MQTT CONNECT untuk pendaftaran dinamis.
            connect(broker, mqttClientId, mqttUsername, mqttPassword);
        }
    
        /**
         * Kirim pesan MQTT CONNECT untuk pendaftaran dinamis.
         *
         * @param serverURL: endpoint untuk pendaftaran dinamis.
         * @param clientId: ID klien.
         * @param username: nama pengguna klien MQTT.
         * @param password: kata sandi klien 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); // MQTT 3.1.1
                connOpts.setUserName(username); // Nama pengguna.
                connOpts.setPassword(password.toCharArray()); // Kata sandi.
                connOpts.setAutomaticReconnect(false); // Nonaktifkan fitur reconnect otomatis berdasarkan aturan MQTT yang dikonfigurasikan untuk pendaftaran dinamis.
                System.out.println("----- parameter registrasi -----");
                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 {
                        // Cetak hanya respons pendaftaran dinamis.
                        if (REGISTER_TOPIC.equals(topic)) {
                            String payload = new String(message.getPayload(), StandardCharsets.UTF_8);
                            System.out.println("----- hasil registrasi -----");
                            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("registrasi gagal: 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();
            }
        }
    
        /**
         * Hasilkan tanda tangan untuk pendaftaran dinamis.
         *
         * @param params: parameter yang diperlukan yang dapat Anda gunakan untuk menghasilkan tanda tangan.
         * @param productSecret: ProductSecret dari produk tempat perangkat milik.
         * @return: tanda tangan dalam format heksadesimal.
         */
        private String sign(JSONObject params, String productSecret) {
    
            // Urutkan parameter permintaan secara alfabetis.
            Set<String> keys = getSortedKeys(params);
    
            // Hapus parameter sign dan signMethod.
            keys.remove("sign");
            keys.remove("signMethod");
    
            // Dapatkan plaintext tanda tangan.
            StringBuffer content = new StringBuffer();
            for (String key : keys) {
                content.append(key);
                content.append(params.getString(key));
            }
    
            // Hasilkan tanda tangan.
            String sign = encrypt(content.toString(), productSecret);
            System.out.println("konten tanda tangan=" + content);
            System.out.println("hasil tanda tangan=" + sign);
    
            return sign;
        }
    
        /**
         * Urutkan kunci objek JSON secara alfabetis.
         *
         * @param json: objek JSON yang ingin Anda urutkan kuncinya.
         * @return: set kunci yang diurutkan secara alfabetis.
         */
        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();
        }
    
        /**
         * Tentukan algoritma enkripsi menggunakan parameter HMAC_ALGORITHM.
         *
         * @param content: plaintext.
         * @param secret: kunci enkripsi.
         * @return: 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;
            }
        }
    
        /**
         * Konversi array biner ke string heksadesimal.
         *
         * @param b: array biner.
         * @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);
    
            // Jika pendaftaran dinamis berhasil, burn DeviceSecret ke perangkat lokal Anda.
        }
    }
  4. Tentukan parameter berikut. Ganti nilai dalam kode contoh sebelumnya dengan informasi perangkat Anda.
    ParameterContohDeskripsi
    regionIdcn-shanghaiID wilayah tempat IoT Platform berjalan. Untuk informasi tentang ID wilayah, lihat Wilayah.
    productKeya1IoK******The ProductKey yang di-burn ke perangkat. Anda dapat masuk ke konsol IoT Platform dan melihat ProductKey di halaman Product Details.
    productSecret6vEu5Qlj5S******The ProductSecret yang di-burn ke perangkat. Anda dapat masuk ke konsol IoT Platform dan melihat ProductSecret di halaman Product Details.
    deviceNameOvenDevice01Nama perangkat.

    IoT Platform memverifikasi DeviceName saat perangkat mengirimkan permintaan aktivasi. Kami sarankan Anda menggunakan pengenal yang dapat diperoleh dari perangkat sebagai DeviceName. Pengenal tersebut bisa berupa alamat MAC, International Mobile Equipment Identity (IMEI), atau SN perangkat.

    broker"ssl://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883"Endpoint yang digunakan dalam pendaftaran dinamis. Format: ssl://" + "${YourInstanceDomain}" + ":" +1883.

    Ganti variabel ${YourInstanceDomain} dengan endpoint MQTT. Untuk informasi tentang cara mendapatkan endpoint MQTT, lihat Kelola endpoint instance.

  5. Jalankan file DynamicRegisterByMqtt.java. Dengan cara ini, perangkat dapat mengirimkan permintaan otentikasi ke IoT Platform. DeviceName, ProductKey, dan ProductSecret termasuk dalam permintaan.

    Gambar berikut menunjukkan hasilnya. Setelah perangkat lolos otentikasi, perangkat menerima DeviceSecret yang diterbitkan oleh IoT Platform. Dalam contoh ini, DeviceSecret adalah 8d1f0cdab49dd229cf3b75**********.

    Result

Apa yang harus dilakukan selanjutnya

Setelah perangkat mendapatkan sertifikat perangkat yang berisi ProductKey, DeviceName, dan DeviceSecret, Anda dapat menggunakan klien MQTT untuk menghubungkan perangkat ke IoT Platform untuk komunikasi data.

Untuk informasi lebih lanjut, lihat Gunakan Klien Paho MQTT Java.