设备认证分为一机一密和一型一密两种方式,本文介绍这两种方式的使用场景。

认证方式

  • 一机一密:在设备上烧写设备的ProductKey、DeviceName、DeviceSecret,然后适配相应的HAL并调用SDK提供的函数连接物联网平台。这种方式要求对设备的产线工具进行一定的修改,需要对每个设备烧写不同的DeviceName和DeviceSecret。

  • 一型一密:设备上烧写设备的ProductKey、ProductSecret,每个设备需要具备自己的唯一标识并将该标识预先上传到阿里云物联网平台,然后调用SDK提供的函数连接云端。这种方式每个设备上烧写的信息是固定的ProductKey和ProductSecret。

获取Link SDK

不同版本的Link SDK下载,请参见SDK获取

一机一密编程

需要根据不用版本的Link SDK设置设备认证信息。
  • 在Link SDK v3.0.1中,需要实现下文认证信息的配置:
    • HAL_GetProductKey
    • HAL_GetDeviceName
    • HAL_GetDeviceSecret
  • 在Link SDK v3.1.0/v3.2.0中,通过IOT_Ioctl设置认证信息:
    • IOT_Ioctl(IOTX_IOCTL_SET_PRODUCT_KEY, g_product_key)
    • IOT_Ioctl(IOTX_IOCTL_SET_DEVICE_NAME, g_device_name)
    • IOT_Ioctl(IOTX_IOCTL_SET_DEVICE_SECRET, g_device_secret)
以Link SDK v3.0.1版本为例,IOT_MQTT_Construct()会调用HAL_GetProductKey()等三个HAL函数去获取设备的身份信息,示例文件参考src\mqtt\examples\mqtt_example.c,代码如下:
int main(int argc, char *argv[])
{
    void                   *pclient = NULL;
    int                     res = 0;
    int                     loop_cnt = 0;
    iotx_mqtt_param_t       mqtt_params;

    memset(&mqtt_params, 0x0, sizeof(mqtt_params));
    mqtt_params.handle_event.h_fp = example_event_handle;

    pclient = IOT_MQTT_Construct(&mqtt_params);
    if (NULL == pclient) {
        EXAMPLE_TRACE("MQTT construct failed");
        return -1;
    }
    ...

} 

一型一密编程

一型一密认证方法使用的流程示意图:

一型一密示意图
实现流程简述:
  1. 设备使用ProductKey、ProductSecret和DeviceName到阿里云物联网平台获取该设备对应的DeviceSecret。
  2. 物联网平台的动态注册服务将查找该设备的DeviceName是否在该ProductKey对应的设备列表,如果该设备在列表中则返回该设备的DeviceSecret。
  3. 设备收到DeviceSecret之后,将使用一机一密的方式计算MQTT连接参数以及签名。
  4. 设备使用计算出来的MQTT连接参数连接物联网平台。
注意
  • 您需要将获取的DeviceSecret持久化到设备,以备后续使用。若获取的DeviceSecret丢失可能导致设备无法上线等严重后果,物联网平台不接受已激活设备重复的动态注册请求。
  • 使用一型一密功能,您必须对每个设备进行预注册,即在阿里云物联网平台的控制台上传每个设备的DeviceName,并且在控制台上打开对应产品的动态注册功能。

实现流程简述步骤中涉及的API如下:

  • 第1步和第2步对应用户接口:IOT_Dynamic_Register()
  • 第3步对应用户接口:IOT_Sign_MQTT()
  • 第4步对应用户接口:IOT_MQTT_Construct()
说明
  • 当设备获取到DeviceSecret之后再次调用IOT_Dynamic_Register()将会返回失败,因此用户编程时获取到DeviceSecret之后需要将其保存到设备本地的存储介质中。
  • 您的程序在调用IOT_Dynamic_Register()之前应该先调用HAL_GetDeviceSecret()查看设备是否已经获取到了DeviceSecret,如果已经获取到,则无需再次调用IOT_Dynamic_Register()
  • 详细参数内容,请参见功能API接口

案例说明

以Link SDK v3.0.1版本为例,一型一密功能的案例程序参考src/dynamic_register/examples/dynreg_example.c文件。

下文对其进行逐段讲解:

  1. 使用一型一密功能,需要包含其头文件dynreg_api.h
    #include <stdio.h>
    #include <string.h>
    #include "infra_types.h"
    #include "infra_defs.h"
    #include "dynreg_api.h"
  2. 准备输入参数region和出入参结构体meta
    iotx_http_region_types_t region = IOTX_HTTP_REGION_SHANGHAI;
    HAL_Printf("dynreg example\n");
    
    memset(&meta,0,sizeof(iotx_dev_meta_info_t));
    HAL_GetProductKey(meta.product_key);
    HAL_GetProductSecret(meta.product_secret);
    HAL_GetDeviceName(meta.device_name);
    说明
    • 入参region = IOTX_CLOUD_REGION_SHANGHAI表示用华东2(上海)作为演示连接站点的场景,您可根据自身需要替换为您的使用站点,详细信息,请参见地域和可用区
    • 入参meta表示从本地获取的ProductKey、ProductSecret和DeviceName。
  3. 调用一型一密的IOT_Dynamic_Register()接口获取DeviceSecret,此接口是一型一密功能点唯一提供的用户接口,若执行成功,在参数meta中将填上从物联网平台成功获取到的DeviceSecret。
    res = IOT_Dynamic_Register(region, &meta);
    if (res < 0) {
        HAL_Printf("IOT_Dynamic_Register failed\n");
        return -1;
    }
    
    HAL_Printf("\nDevice Secret: %s\n\n", meta.device_secret);

功能API接口

IOT_Dynamic_Register
  • 原型:
    int32_t IOT_Dynamic_Register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta);
  • 接口说明:根据输入参数中指定的站点区域,以及ProductKey和ProductSecret,请求物联网平台为DeviceName指定的设备申请DeviceSecret。
  • 参数说明:
    参数 数据类型 方向 说明
    region iotx_http_region_types_t 输入 设备将要工作的区域,例如华东2(上海)、亚太东北1(东京)、美国西部1(硅谷)、亚太东南1(新加坡)等,完整内容,请参见地域和可用区
    meta iotx_dev_meta_info_t * 输入输出 输入的时候带入设备的ProductKey、ProductSecret和DeviceName,输出的时候返回从物联网平台获取到的DeviceSecret。
  • 返回结果:
    返回结果 说明
    =0 请求成功。
    <0 请求失败。
IOT_MQTT_Construct
  • 原型:
    void *IOT_MQTT_Construct(iotx_mqtt_param_t *pInitParams);
  • 接口说明:初始化MQTT建连参数,建立MQTT连接。
  • 参数说明:
    参数 数据类型 方向 说明
    pInitParams iotx_mqtt_param_t * 输入 MQTT建连参数。
  • 返回结果:
    返回结果 说明
    非空对象 请求成功。
    NULL(空对象) 请求失败。
IOT_Sign_MQTT
  • 原型:
    int32_t IOT_Sign_MQTT(iotx_mqtt_region_types_t region, iotx_dev_meta_info_t *meta, iotx_sign_mqtt_t *signout)
  • 接口说明:计算MQTT签名。
  • 参数说明:
    参数 数据类型 方向 说明
    region iotx_http_region_types_t 输入 设备所属的区域。
    meta iotx_dev_meta_info_t * 输入 签名所需的信息,存放设备的标识字符串,包括ProductKey、DeviceName等。
    signout iotx_sign_mqtt_t * 输出 签名结果,包括username、password、clientid、hostname等。
  • 返回结果:
    返回结果 说明
    =0 请求成功。
    <0 请求失败。