设备安全认证
更新时间: 2023-04-10

设备接入物联网平台之前,需通过身份认证。

目前,平台支持使用设备密钥进行设备身份认证。

# 认证方式

创建产品,然后在该产品下添加设备,获取物联网平台颁发的ProductSecret、DeviceSecret等密钥。设备接入物联网平台时,会使用物联网平台颁发的密钥信息,进行身份认证。

针对不同的使用环境,物联网平台提供以下四种设备密钥认证方案。

一机一密:每台设备烧录自己的设备证书(ProductKey、DeviceName和DeviceSecret)。

一型一密预注册:同一产品下设备烧录相同产品证书(ProductKey和ProductSecret)。开通产品的动态注册功能,设备通过动态注册获取DeviceSecret。

两种方案在易用性和安全性上各有优势,您可以根据设备所需的安全等级和实际的产线条件灵活选择。

对比项 一机一密 一型一密
设备端烧录信息 ProductKey、DeviceName、DeviceSecret ProductKey、ProductSecret
云端是否需要开启动态注册 无需开启,默认支持。 需打开动态注册开关。
是否需要提前在物联网平台创建设备,注册DeviceName 需要,产品下DeviceName唯一。 需要,产品下DeviceName唯一。
产线烧录要求 逐一烧录设备证书,需确保设备证书的安全性。 批量烧录相同的产品证书,需确保产品证书的安全存储。
安全性 较高 一般

# 认证流程

device-pub.png

  1. 设备端使用平台生成的设备密钥,按认证签名算法生成签名,向物联网平台请求鉴权,获取设备连接平台使用的真实配置信息

  2. 认证通过,平台返回连接地址、用户名、密码等信息,设备使用以上信息连接平台。

    设备端根据需要可以将获得的连接信息持久化保存到设备中,之后再连接平台时可以直接使用,而无需每次都请求认证接口获取连接信息,此时需要开启产品的永久密钥开关以及在认证时选择返回永久密钥。

# 一机一密认证方法

一机一密认证要求设备烧录自身的密钥,密钥与设备一对一绑定,每个设备的密钥不同。

# 签名计算

  1. 将接口路径、分钟级时间戳和请求参数(body的JOSN字符串)拼接成待加密字符串authStringPrefix,参数之间以换行符"\n"连接,没有请求参数时,填"null"

示例: /v1/devices/zfm8n1p5y1qzc09a/test01/test01/resources 26944410 {"resourceType":"MQTT"} 或 /v1/devices/zfm8n1p5y1qzc09a/test01/test01/resources 26944410 null

  1. 分别获取deviceSecret、authStringPrefix的字节数组

  2. 使用deviceSecret字节数组对上述认证字符串字节数组进行HmacSHA256进行加密

  3. 将加密后的byte数组进行Base64编码得到signature,并进行urlencode处理

  4. 将最终得到的signature和分钟级时间戳放到请求的header中

不同编程语言实现签名算法时,对字符串的处理方法存在差异,以下两点需特别注意:

  • body json string不要带空格,如python的json.dumps()为了美观会加上空格,导致鉴权失败,请指定参数separators=(',','😂

  • urlencode处理时需对全部字符进行转换,例如python中使用urllib.parse.quote()时默认不对‘/’进行编码,需要是应用urllib.parse.quote('待转换字符串', safe='')

# 请求鉴权

认证地址: 在平台控制台实例详情页获取,认证地址在不同的项目中可能不一致

image.png

Path: /v1/devices/{instanceId}/{productkey}/{deviceName}/resources

Method: POST

Headers

参数名称 参数值 是否必须 示例 备注
Content-Type application/json
signature
expiryTime 分钟级时间戳,当前时间前后十分钟有效

路径参数

参数名称 示例 备注
instanceId 平台实例ID
productkey 产品标识
deviceName 设备标识

Body

名称类型是否必须默认值备注
resourceTypestring必须MQTT/EVS

# 返回参数

名称类型
resourceType string
content object

# 返回示例

{
    "resourceType":"MQTT",
    "content":{
        "password":"418b803b0dc12206a6438901ad814",
        "clientId":"a63c3cd470bc27ff287f3dcac45b",
        "port":1883,
        "broker":"ahvmcra.iot.gz.AIoTbce.com",
        "username":"thingidp@ahvmcra|a63c3cd470bc27ff287f3dcac45b|0|MD5"
    }
}

# 一型一密认证方法

一型一密认证时设备烧录统一的产品密钥,同一产品下不同设备烧录相同密钥,并在认证时携带产品密钥及设备唯一标识换取一机一密密钥。一型一密在产线批量烧录的场景下更加简便,同时需注意保护产品线密钥不要泄露。

# 签名计算

  1. 将接口路径、分钟级时间戳和请求参数(body的JOSN字符串)拼接成待加密字符串authStringPrefix,参数之间以换行符"\n"连接,没有请求参数时,填"null"

示例: /v1/devices/zfm8n1p5y1qzc09a/test01/test01/register 26944410 null

  1. 分别获取productSecret、authStringPrefix的字节数组

  2. 使用productSecret字节数组对上述认证字符串字节数组进行HmacSHA256进行加密

  3. 将加密后的byte数组进行Base64编码得到signature,并进行urlencode处理

  4. 将最终得到的signature和分钟级时间戳放到请求的header中

不同编程语言实现签名算法时,对字符串的处理方法存在差异,以下两点需特别注意:

  • body json string不要带空格,如python的json.dumps()为了美观会加上空格,导致鉴权失败,请指定参数separators=(',','😂

  • urlencode处理时需对全部字符进行转换,例如python中使用urllib.parse.quote()时默认不对‘/’进行编码,需要是应用urllib.parse.quote('待转换字符串', safe='')

# 请求设备注册鉴权

认证地址: 与一机一密一致

Path: /v1/devices/{instanceId}/{productkey}/{deviceName}/register

Method: POST

Headers

参数名称 参数值 是否必须 示例 备注
Content-Type application/json
signature
expiryTime 分钟级时间戳,当前时间前后十分钟有效
algorithmType [DEFAULT, SHC],非必须

路径参数

参数名称 示例 备注
instanceId 平台实例ID
productkey 产品标识
deviceName 设备标识

Body

{}

# 返回参数

名称类型
deviceSecretstring

# 返回示例

{
    "deviceSecret":"418b803b0dc12206a6438901ad814"
}

# 请求设备鉴权

设备通过一型一密鉴权获得设备密钥后,继续使用此密钥按一机一密认证流程进行认证