This topic describes how to dynamically register the devices that use the HTTPS protocol and obtain the DeviceSecrets. The DeviceSecrets are required for authentication when you connect the devices to IoT Platform. In this example, the sample code for Java is used.

Prerequisites

The following steps that are described in the Unique-certificate-per-product verification topic are performed:

  1. Create a product.
  2. Enable dynamic registration.
  3. Add a device.
  4. Install the device certificates on the devices.

Background information

IoT Platform supports multiple authentication methods for devices. For more information, see Authenticate a device.

You can establish HTTPS connections to perform pre-registration unique-certificate-per-product authentication. For more information about the topics and parameters that are used for HTTPS-based dynamic registration, see HTTPS-based dynamic registration of directly connected devices.

Prepare the development environment

In this example, the development environment consists of the following components:

Procedure

  1. Open IntelliJ IDEA and create a Maven project. In this example, the HTTPS dynamic registration project is created.
  2. In the pom.xml file, add the following Maven dependencies and click Load Maven Changes to download the packages.
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.83</version>
    </dependency>
  3. Go to the \HTTPS dynamic registration \src\main\java directory and create a Java class. In this example, the DynamicRegisterByMqtt class is created. Copy the following code to the file.
    Note
    • If the device is not activated, you can perform dynamic registration multiple times. However, only the latest DeviceSecret is valid. Make sure that the latest DeviceSecret is burned on the device.
    • If the device is activated, you must call the ResetThing operation to reset the registration status of the device to unregistered in the IoT Platform console. Then, you can dynamically register the device.
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.URL;
    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 javax.net.ssl.HttpsURLConnection;
    
    import com.alibaba.fastjson.JSONObject;
    
    /**
     * Perform dynamic registration for a device. 
     */
    public class DynamicRegisterByHttps {
    
        // The ID of the region where your product resides. 
        private static String regionId = "cn-shanghai";
    
        // The encryption algorithm. Valid values: HmacMD5, HmacSHA1, and HmacSHA256. The specified value must be the same as the value of the signMethod parameter. 
        private static final String HMAC_ALGORITHM = "hmacsha1";
    
        /**
         * Dynamic registration. 
         * 
         * @param productKey: the ProductKey of the device.
         * @param productSecret: the ProductSecret of the device.
         * @param deviceName: the DeviceName of the device.
         * @throws Exception
         */
        public void register(String productKey, String productSecret, String deviceName) throws Exception {
    
            // The requested URL. 
            URL url = new URL("https://iot-auth." + regionId + ".aliyuncs.com/auth/register/device");
    
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
            conn.setDoOutput(true);
            conn.setDoInput(true);
    
            // Obtain the output stream of the URLConnection object. 
            PrintWriter out = new PrintWriter(conn.getOutputStream());
            // Send request parameters. 
            out.print(registerdBody(productKey, productSecret, deviceName));
            // Clear the content of the cache. 
            out.flush();
    
            // Obtain the input stream of the URLConnection object. 
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            // Obtain a response from the endpoint. 
            String result = "";
            String line = "";
            while ((line = in.readLine()) != null) {
                result += line;
            }
            System.out.println("----- register result -----");
            System.out.println(result);
    
            // Close the input and output streams. 
            in.close();
            out.close();
            conn.disconnect();
        }
    
        /**
         * Generate a request for dynamic registration. 
         * 
         * @param productKey: the ProductKey of the device.
         * @param productSecret: the ProductSecret of the device.
         * @param deviceName: the DeviceName of the device.
         * @return: the response payloads.
         */
        private String registerdBody(String productKey, String productSecret, String deviceName) {
    
            // Obtain a random value. 
            Random r = new Random();
            int random = r.nextInt(1000000);
    
            // The required parameters for dynamic registration. 
            JSONObject params = new JSONObject();
            params.put("productKey", productKey);
            params.put("deviceName", deviceName);
            params.put("random", random);
            params.put("signMethod", HMAC_ALGORITHM);
            params.put("sign", sign(params, productSecret));
    
            // Concatenate the payloads. 
            StringBuffer payload = new StringBuffer();
            for (String key : params.keySet()) {
                payload.append(key);
                payload.append("=");
                payload.append(params.getString(key));
                payload.append("&");
            }
            payload.deleteCharAt(payload.length() - 1);
    
            System.out.println("----- register payload -----");
            System.out.println(payload);
    
            return payload.toString();
        }
    
        /**
         * Generate a signature for dynamic registration. 
         * 
         * @param params: the parameters that are required to generate a signature.
         * @param productSecret: the ProductSecret of the device.
         * @return: a hexadecimal signature string.
         */
        private String sign(JSONObject params, String productSecret) {
    
            // Sort request parameters in alphabetical order. 
            Set<String> keys = getSortedKeys(params);
    
            // Remove the sign and signMethod parameters
            keys.remove("sign");
            keys.remove("signMethod");
    
            // Obtain the plaintext of the signature. 
            StringBuffer content = new StringBuffer();
            for (String key : keys) {
                content.append(key);
                content.append(params.getString(key));
            }
    
            // Generate the signature. 
            String sign = encrypt(content.toString(), productSecret);
            System.out.println("sign content=" + content);
            System.out.println("sign result=" + sign);
    
            return sign;
        }
    
        /**
         * Convert a JSON object to a set of key-value pairs. 
         *
         * @param json: the JSON object that you want to convert.
         * @return: the key-value pairs that are converted from the JSON object.
         */
        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();
        }
    
        /**
         * Specify an encryption algorithm for the HMAC_ALGORITHM parameter. 
         * 
         * @param content: the plaintext.
         * @param secret: the encryption 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;
            }
        }
    
        /**
         * Convert a binary array to a hexadecimal string. 
         * 
         * @param b: the binary array.
         * @return: a 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. 
            DynamicRegisterByHttps client = new DynamicRegisterByHttps();
            client.register(productKey, productSecret, deviceName);
    
            // If the dynamic registration is successful, persist the DeviceSecret on your local device. 
        }
    }
  4. Configure the parameters. Replace the values in the preceding sample code with your device information. The following table describes the parameters.
    Parameter Example value Description
    regionId cn-shanghai The ID of the region where IoT Platform runs. For information about the format of region IDs, see Regions.
    productKey a1IoK****** The ProductKey that is burned to the device. You can log on to the IoT Platform console and view the ProductKey on the Product Details page.
    productSecret 6vEu5Qlj5S****** The ProductSecret that is burned to the device. You can log on to the IoT Platform console and view the ProductSecret on the Product Details page.
    deviceName OvenDevice01 The name of the device.

    IoT Platform checks the DeviceName when a device initiates an activation request. We recommend that you use an identifier that can be obtained from the device as the DeviceName. The identifier can be the MAC address, International Mobile Equipment Identity (IMEI) number, or serial number (SN) of the device.

  5. Run the DynamicRegisterByMqtt.java file. This way, the device can send an authentication request to IoT Platform. The DeviceName, ProductKey, and ProductSecret are included in the request. The following figure shows the result. After the device passes the authentication, the device receives a DeviceSecret that is issued by IoT Platform. In this example, the DeviceSecret is 6b14088fa377e8f852d82f7f********. Result

What to do next

After the device obtains the device certificate that contains the ProductKey, DeviceName, and DeviceSecret, you can use the MQTT client to connect the device to IoT Platform for data communication.

For more information, see Use the Paho MQTT Java client.