tencent cloud

Feedback

SDK for C Connection Description

Last updated: 2023-07-27 10:41:13

    To ensure security, IoT Hub verifies the validity of each connected device. For this reason, it provides multiple authentication methods to meet the needs for connection of devices with different resources in different use cases.

    Device Identity Information

    Depending on the form of device key, devices are divided into certificate-authenticated devices and key-authenticated devices. Certificate authentication is more secure, but it consumes more software and hardware resources.

    • Certificate-authenticated devices must carry the following four pieces of information before it can pass the authentication by the platform: product ID (ProductId), device name (DeviceName), device certificate (DeviceCert), and device private key (DevicePrivateKey), among which, the certificate and private key files are generated by the platform and correspond to each other.
    • Key-authenticated devices must carry the following three pieces of information before it can pass the authentication by the platform: product ID (ProductId), device name (DeviceName), and device key (DeviceSecret), among which, the device key is generated by the platform.

    The device key is determined by setting the authentication method during product creation as shown below:

    Device Identity Information Burning

    Device information burning is divided into preset burning and dynamic burning, which differ in terms of convenience and security.

    Preset burning

    After a product is created, you can create devices one by one in the IoT Hub console or through TencentCloud API, get their corresponding device information, and burn the above three or four pieces of information into a non-volatile medium in a specific step of device production, so that the device SDK can read the stored device information during running for device authentication.

    Dynamic burning

    • Preset burning: this involves performing personalized production actions in the mass production process and thus affects the production efficiency. To improve the ease of use, the platform supports dynamic burning. This feature is implemented as follows: after a product is created, its dynamic registration feature can be used to generate a product key (ProductSecret). Unified product information can be burned for all devices under it in the production process, i.e., product ID (ProductId) and product key (ProductSecret). After the devices are shipped, the device identity information can be obtained through dynamic registration and then saved, and then obtained three or four pieces of information can be used for device authentication.
    • Device name (DeviceName) generation for dynamic burning: if automatic device creation is used during dynamic registration, device names can be generated by devices themselves, which are generally device IMEIs or MAC addresses but must be unique under the same product ID (ProductId). If automatic device creation is not used during dynamic registration, device names should be entered on the platform in advance, and the platform will verify whether the requested device names are validly entered during dynamic device registration. This can reduce the security risks in case of product key leakage.
    Note:

    For dynamic registration, you should ensure the security of the product key (ProductSecret); otherwise, major security risks may arise.

    Programming for Authenticating Preset Burnt Devices

    Writing device information

    For certificate-authenticated devices, implement the following HAL APIs:

    HAL_API Description
    HAL_SetProductID Sets the product ID, which must be stored on a non-volatile storage medium
    HAL_SetDevName Sets the device name, which must be stored on a non-volatile storage medium
    HAL_SetDevCertName Sets the device certificate file name. The certificate file should be placed in the certs directory
    HAL_SetDevPrivateKeyName Sets the device private key file name. The private key file should be placed in the certs directory

    For key-authenticated devices, implement the following HAL APIs:

    HAL_API Description
    HAL_SetProductID Sets the product ID, which must be stored on a non-volatile storage medium
    HAL_SetDevName Sets the device name, which must be stored on a non-volatile storage medium
    HAL_SetDevSec Sets the device key, which must be stored on a non-volatile storage medium. We recommend you encrypt and scramble it

    Getting device information

    For certificate-authenticated devices, implement the following HAL APIs:

    HAL_API Description
    HAL_GetProductID Gets product ID
    HAL_GetDevName Gets device name
    HAL_GetDevCertName Gets device certificate file name
    HAL_GetDevPrivateKeyName Gets device certificate private key file name

    For key-authenticated devices, implement the following HAL APIs:

    HAL_API Description
    HAL_GetProductID Gets product ID
    HAL_GetDevName Gets device name
    HAL_GetDevSec Gets device key. If it is encrypted and scrambled during write, it should be decrypted and descrambled during read

    Application demos

    • Initialize the connection parameters
    static DeviceInfo sg_devInfo;
    
    static int _setup_connect_init_params(MQTTInitParams* initParams)
    {
        int ret;
        
        ret = HAL_GetDevInfo((void *)&sg_devInfo);    
        if(QCLOUD_ERR_SUCCESS != ret){
            return ret;
        }
            
        initParams->device_name = sg_devInfo.device_name;
        initParams->product_id = sg_devInfo.product_id;
         ......
    }    
    
    • Get the device information
    int HAL_GetDevInfo(void *pdevInfo)
    {
        int ret;
        DeviceInfo *devInfo = (DeviceInfo *)pdevInfo;
            
        memset((char *)devInfo, 0, sizeof(DeviceInfo));
        ret = HAL_GetProductID(devInfo->product_id, MAX_SIZE_OF_PRODUCT_ID);
        ret |= HAL_GetDevName(devInfo->device_name, MAX_SIZE_OF_DEVICE_NAME); 
        
    #ifdef     AUTH_MODE_CERT
        ret |= HAL_GetDevCertName(devInfo->devCertFileName, MAX_SIZE_OF_DEVICE_CERT_FILE_NAME);
        ret |= HAL_GetDevPrivateKeyName(devInfo->devPrivateKeyFileName, MAX_SIZE_OF_DEVICE_KEY_FILE_NAME);
    #else
        ret |= HAL_GetDevSec(devInfo->devSerc, MAX_SIZE_OF_DEVICE_SERC);
    #endif 
    
        if(QCLOUD_ERR_SUCCESS != ret){
            Log_e("Get device info err");
            ret = QCLOUD_ERR_DEV_INFO;
        }
    
        return ret;
    }
    
    
    • Generate the authentication parameters
    static int _serialize_connect_packet(unsigned char *buf, size_t buf_len, MQTTConnectParams *options, uint32_t *serialized_len) {
                ......
                ......
        int username_len = strlen(options->client_id) + strlen(QCLOUD_IOT_DEVICE_SDK_APPID) + MAX_CONN_ID_LEN + cur_timesec_len + 4;
        options->username = (char*)HAL_Malloc(username_len);
        get_next_conn_id(options->conn_id);
        HAL_Snprintf(options->username, username_len, "%s;%s;%s;%ld", options->client_id, QCLOUD_IOT_DEVICE_SDK_APPID, options->conn_id, cur_timesec);
    
    #if defined(AUTH_WITH_NOTLS) && defined(AUTH_MODE_KEY)
         if (options->device_secret != NULL && options->username != NULL) {
             char                sign[41]   = {0};
             utils_hmac_sha1(options->username, strlen(options->username), sign, options->device_secret, options->device_secret_len);
             options->password = (char*) HAL_Malloc (51);
             if (options->password == NULL) IOT_FUNC_EXIT_RC(QCLOUD_ERR_INVAL);
             HAL_Snprintf(options->password, 51, "%s;hmacsha1", sign);
         }
    #endif
                ......
    }
    

    Programming for Authenticating Dynamically Burnt Devices

    • Determine whether to initiate a dynamic request
    int main(int argc, char **argv) {
                ......
        memset((char *)&sDevInfo, 0, sizeof(DeviceInfo));
        ret = HAL_GetProductID(sDevInfo.product_id, MAX_SIZE_OF_PRODUCT_ID);
        ret |= HAL_GetProductKey(sDevInfo.product_key, MAX_SIZE_OF_PRODUCT_KEY);
        ret |= HAL_GetDevName(sDevInfo.device_name, MAX_SIZE_OF_DEVICE_NAME);  // Dynamic registration. We recommend you use a unique identifier of the device as the device name, such as chip ID or IMEI
        
    #ifdef     AUTH_MODE_CERT
        ret |= HAL_GetDevCertName(sDevInfo.devCertFileName, MAX_SIZE_OF_DEVICE_CERT_FILE_NAME);
        ret |= HAL_GetDevPrivateKeyName(sDevInfo.devPrivateKeyFileName, MAX_SIZE_OF_DEVICE_KEY_FILE_NAME);
        if(QCLOUD_ERR_SUCCESS != ret){
            Log_e("Get device info err");
            return QCLOUD_ERR_FAILURE;
        }
        /*You need to modify the logic for empty device information based on your own product conditions. Here is only a sample*/
        if(!strcmp(sDevInfo.devCertFileName, QCLOUD_IOT_NULL_CERT_FILENAME)
            ||!strcmp(sDevInfo.devPrivateKeyFileName, QCLOUD_IOT_NULL_KEY_FILENAME)){
            Log_d("dev Cert not exist!");
            infoNullFlag = true;
        }else{
            Log_d("dev Cert exist");
        }
    #else
        ret |= HAL_GetDevSec(sDevInfo.devSerc, MAX_SIZE_OF_PRODUCT_KEY);
        if(QCLOUD_ERR_SUCCESS != ret){
            Log_e("Get device info err");
            return QCLOUD_ERR_FAILURE;
        }
        /*You need to modify the logic for empty device information based on your own product conditions. Here is only a sample*/
        if(!strcmp(sDevInfo.devSerc, QCLOUD_IOT_NULL_DEVICE_SECRET)){
            Log_d("dev psk not exist!");
            infoNullFlag = true;
        }else{
            Log_d("dev psk exist");
        }
    #endif 
                ......
    
    }
    
    
    • Initiate a dynamic request and save the requested device information
        /*The device information is empty. Initiate device registration. Note: after successful device registration and connection, registration cannot be initiated again, so please save the device information properly*/
        if(infoNullFlag){
            if(QCLOUD_ERR_SUCCESS == qcloud_iot_dyn_reg_dev(&sDevInfo)){
                
                ret = HAL_SetDevName(sDevInfo.device_name);
    #ifdef     AUTH_MODE_CERT
                ret |= HAL_SetDevCertName(sDevInfo.devCertFileName);
                ret |= HAL_SetDevPrivateKeyName(sDevInfo.devPrivateKeyFileName);        
    #else
                ret |= HAL_SetDevSec(sDevInfo.devSerc);
    #endif
                if(QCLOUD_ERR_SUCCESS != ret){
                    Log_e("devices info save fail");
                }else{
    #ifdef     AUTH_MODE_CERT
                    Log_d("dynamic register success, productID: %s, devName: %s, CertFile: %s, KeyFile: %s", \
                            sDevInfo.product_id, sDevInfo.device_name, sDevInfo.devCertFileName, sDevInfo.devPrivateKeyFileName);
    #else
                    Log_d("dynamic register success,productID: %s, devName: %s, devSerc: %s", \
                            sDevInfo.product_id, sDevInfo.device_name, sDevInfo.devSerc);
    #endif
                }
            }else{
                Log_e("%s dynamic register fail", sDevInfo.device_name);
            }
        }
    

    After the device information is dynamically requested successfully, the preset burning feature will be completed. The subsequent authentication process is the same as that with preset burning.

    Contact Us

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support