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.
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.
The device key is determined by setting the authentication method during product creation as shown below:
Device information burning is divided into preset burning and dynamic burning, which differ in terms of convenience and security.
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.
Note:For dynamic registration, you should ensure the security of the product key (ProductSecret); otherwise, major security risks may arise.
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 |
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 |
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;
......
}
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;
}
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
......
}
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
......
}
/*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.
Was this page helpful?