Paho-MQTT C使用ID2-KM接入阿里云物聯(lián)網(wǎng)平臺(tái)
本文介紹了開源Paho MQTT embeded-c如何通過(guò)更安全的身份認(rèn)證方式(ID2)連接到阿里云物聯(lián)網(wǎng)平臺(tái),并建立安全傳輸通道。
1. 術(shù)語(yǔ)
Soft-KM(Key Management)密鑰管理,由阿里提供的軟件安全沙箱,基于軟件加固和虛擬化技術(shù)提供對(duì)密鑰(IoT ID2)的安全保護(hù)。
OSA(Operation System Abstractor Layer)操作系統(tǒng)抽象層,定義內(nèi)存申請(qǐng)和釋放、日志打印、系統(tǒng)時(shí)間、網(wǎng)絡(luò)通信等接口,非遵循POSIX標(biāo)準(zhǔn)的OS,需重新適配這些接口。
HAL(Hardware Abstractor Layer)硬件抽象層,根據(jù)設(shè)備硬件特性,完成對(duì)加解密算法、設(shè)備唯一ID、密鑰管理和數(shù)據(jù)安全存儲(chǔ)的接口適配。
ID2 OTP(One-Time Provisioning)一次性燒錄,也稱ID2空發(fā),指設(shè)備在第一次聯(lián)網(wǎng)時(shí),通過(guò)網(wǎng)絡(luò)請(qǐng)求,下發(fā)ID2數(shù)據(jù)燒錄到設(shè)備中。
TLS(Transport Layer Security)安全傳輸層協(xié)議, 用于兩個(gè)通信實(shí)體之間,保護(hù)通信數(shù)據(jù)的私密性和完整性。
IoT(Internet of things)物聯(lián)網(wǎng),基于互聯(lián)網(wǎng)實(shí)現(xiàn)萬(wàn)物互聯(lián)。
阿里云物聯(lián)網(wǎng)平臺(tái)(Link Platform)阿里云物聯(lián)網(wǎng)平臺(tái),提供物聯(lián)網(wǎng)的設(shè)備管理。
?
2. ID2產(chǎn)品架構(gòu)
ID2控制中心:
ID2的Web控制臺(tái),提供對(duì)ID2產(chǎn)線灌裝、ID2產(chǎn)品和配額申請(qǐng)、以及ID2使用統(tǒng)計(jì)的管理。
ID2服務(wù)中心:
ID2在云端的應(yīng)用,提供ID2的各種安全能力,包括ID2密鑰安全分發(fā)、設(shè)備認(rèn)證、基于ID2的安全連接協(xié)議等;同時(shí),提供各種能力的云端接口,支持業(yè)務(wù)平臺(tái)的二次開發(fā),支持不同的安全業(yè)務(wù)需求和場(chǎng)景。
ID2 Client SDK:
ID2在設(shè)備端的功能組件和軟件開發(fā)框架,可支持不同操作系統(tǒng)和不同硬件,為IoT設(shè)備提供基于ID2的端到端的設(shè)備認(rèn)證、數(shù)據(jù)加解密等各種安全能力。
?
3. ID2接入流程
3.1 概述:
阿里云物聯(lián)網(wǎng)平臺(tái)接入的方式,ID2已默認(rèn)同物聯(lián)網(wǎng)平臺(tái)打通,因此不需要進(jìn)行服務(wù)端對(duì)接。
設(shè)備建連的過(guò)程,IoT設(shè)備通過(guò)Paho MQTT Client SDK調(diào)用ID2-iTLS,進(jìn)行設(shè)備認(rèn)證和會(huì)話密鑰協(xié)商,最后建立數(shù)據(jù)安全傳輸通道。
設(shè)備建連成功后,IoT設(shè)備和物聯(lián)網(wǎng)平臺(tái),通過(guò)安全通道進(jìn)行應(yīng)用數(shù)據(jù)的安全傳輸。
?
ID2對(duì)接步驟如下:
3.2 創(chuàng)建產(chǎn)品:
點(diǎn)擊選擇的實(shí)例,在左側(cè)導(dǎo)航欄,選擇設(shè)備管理 > 產(chǎn)品,單擊創(chuàng)建產(chǎn)品:
填寫產(chǎn)品信息,認(rèn)證方式選擇ID2:
3.3 購(gòu)買ID2:
購(gòu)買ID2認(rèn)證授權(quán):
點(diǎn)擊購(gòu)買鏈接 - 購(gòu)買ID2認(rèn)證授權(quán)。
購(gòu)買數(shù)量和有效期:
分配ID2認(rèn)證授權(quán):
2.1 登錄到ID2控制臺(tái),進(jìn)入入門指引 - IoT設(shè)備身份認(rèn)證頁(yè)面,選擇“與阿里云物聯(lián)網(wǎng)平臺(tái)組合使用”,點(diǎn)擊“開始接入”。
2.2 在“配置產(chǎn)品“步驟中,“選擇產(chǎn)品”,然后“分配ID2授權(quán)數(shù)量”。
3.4 設(shè)備端對(duì)接:
3.4.1 ID2 SDK框架:
IoT Application:
設(shè)備端的應(yīng)用程序,負(fù)責(zé)業(yè)務(wù)數(shù)據(jù)處理,包括設(shè)備認(rèn)證、設(shè)備建連和數(shù)據(jù)收發(fā)等。
Paho MQTT Client SDK:
Eclipse Paho MQTT C/C++ Client開源代碼實(shí)現(xiàn),提供基于MQTT協(xié)議的數(shù)據(jù)管理。
ID2 Client SDK:
iTLS:輕量的安全連接協(xié)議TLS,基于ID2完成TLS的握手認(rèn)證和密鑰協(xié)議,提供應(yīng)用數(shù)據(jù)的收發(fā)。
ID2:IoT設(shè)備認(rèn)證的對(duì)外接口,上層應(yīng)用/協(xié)議基于此接口進(jìn)行開發(fā)。
KM:密鑰管理模塊,支持不同形式的載體:
Soft-KM:軟件沙箱,基于軟件加固和虛擬化技術(shù)提供對(duì)ID2密鑰的安全保護(hù)。
SE:安全芯片,基于物理防護(hù)機(jī)制,提供對(duì)ID2密鑰的安全保護(hù),通過(guò)AT指令對(duì)設(shè)備提供ID2的運(yùn)算。
Crypto:提供統(tǒng)一的加解密算法接口。
OSA:操作系統(tǒng)適配接口,廠商需根據(jù)使用的OS,重新進(jìn)行接口適配。
HAL:硬件適配接口,提供算法庫(kù)和Soft-KM的適配接口,廠商需根據(jù)選擇的硬件平臺(tái),重新進(jìn)行接口適配。
3.4.2 ID2 設(shè)備端SDK獲?。?/b>
ID2 設(shè)備端 SDK下載:
可以到ID2安全Agent參考頁(yè)面下載ID2設(shè)備端的SDK。
ID2 Release Package目錄:
目錄/文件 | 說(shuō)明 |
app | 測(cè)試用例,包括HAL和ID2 |
include | 頭文件 |
libs | ID2模塊的靜態(tài)庫(kù) |
makefile | 編譯腳本 |
make.rules | 編譯系統(tǒng)配置文件,可配置編譯工具鏈和編譯參數(shù) |
sample | ID2的示例代碼 |
src | 需適配的OSA和HAL接口和參考實(shí)現(xiàn) |
3.4.3 ID2 設(shè)備端SDK對(duì)接:
設(shè)備端適配:
根據(jù)選擇的OS和硬件平臺(tái),完成ID2 SDK的移植。
?
基于ID2 Release Package進(jìn)行移植,OSA和HAL需要廠商根據(jù)接口說(shuō)明進(jìn)行重新適配。
第一步:OSA接口適配:
實(shí)現(xiàn)src/osa/ls_osa.c中的接口:
已提供Linux系統(tǒng)的參考實(shí)現(xiàn),可只實(shí)現(xiàn)其中的基礎(chǔ)接口和網(wǎng)絡(luò)接口。
第二步:HAL接口適配:
實(shí)現(xiàn)src/hal/km/demo/ls_hal_km.c中的接口:
已提供Linux系統(tǒng)的參考實(shí)現(xiàn):
單獨(dú)預(yù)留的KM安全分區(qū)大于2K, 且需保證在系統(tǒng)升級(jí)和重啟時(shí),分區(qū)數(shù)據(jù)不被破壞。
ls_hal_get_id接口,需使用設(shè)備硬件唯一標(biāo)識(shí)。
第三步:HAL接口測(cè)試:
修改makefile.rules的編譯配置文件:
配置目標(biāo)平臺(tái)(pLat := xxx)。
CROSS_COMPILE設(shè)置對(duì)應(yīng)的編譯工具鏈。
CFLAGS設(shè)置編譯的配置參數(shù)。
執(zhí)行編譯"make clean & make"。
正確運(yùn)行程序hal_test,可得到如下成功日志:
"HAL Key Management Test Pass"。
設(shè)備端集成:
Paho MQTT調(diào)用設(shè)備端ID2的接口,完成相應(yīng)的設(shè)備認(rèn)證、數(shù)據(jù)加密等安全功能。
下文通過(guò)在Linux系統(tǒng),演示如何集成和使能ID2的認(rèn)證和數(shù)據(jù)加密能力
第一步:下載Paho MQTT代碼:
Paho MQTT Embeded-c代碼下載:
第二步:MQTT集成ID2的安全通道:
MQTTClient-C/src目錄,在Linux下創(chuàng)建libs,拷貝已適配好的ID2靜態(tài)庫(kù)和頭文件。
linux/MQTTLinux.h - 更新Network結(jié)構(gòu)體和接口:
typedef struct Network
{
char *product_key;
char *product_secret;
uintptr_t handle;
int (*mqttread) (struct Network*, unsigned char*, int, int);
int (*mqttwrite) (struct Network*, unsigned char*, int, int);
} Network;
int mqtt_itls_read(Network*, unsigned char*, int, int);
int mqtt_itls_write(Network*, unsigned char*, int, int);
DLLExport void NetworkSetConfig(Network *, char *, char *);
DLLExport void NetworkInit(Network*);
DLLExport int NetworkConnect(Network*, char*, int);
DLLExport void NetworkDisconnect(Network*);
Network結(jié)構(gòu)體:
增加product_key成員:阿里云物聯(lián)網(wǎng)平臺(tái)(LP)- 產(chǎn)品標(biāo)識(shí)
增加product_secret成員:阿里云物聯(lián)網(wǎng)平臺(tái)(LP)- 產(chǎn)品密鑰
變更網(wǎng)絡(luò)句柄類型:my_socket(int) -> handle(uintptr_t)
Network網(wǎng)絡(luò)接口:
增加NetworkSetConfig:用于配置LP產(chǎn)品標(biāo)識(shí)和產(chǎn)品密鑰
linux/MQTTLinux.c - 適配Network網(wǎng)絡(luò)接口:
#include "hal_itls.h"
int mqtt_itls_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
return hal_itls_read(n->handle, buffer, len, timeout_ms);
}
int mqtt_itls_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
return hal_itls_write(n->handle, buffer, len, timeout_ms);
}
void NetworkSetConfig(Network* n, char *product_key, char *product_secret)
{
n->product_key = product_key;
n->product_secret = product_secret;
}
void NetworkInit(Network* n)
{
n->handle = 0;
n->mqttread = mqtt_itls_read;
n->mqttwrite = mqtt_itls_write;
}
int NetworkConnect(Network* n, char* addr, int port)
{
n->handle = hal_itls_establish(addr, port, n->product_key, n->product_secret);
if (n->handle == 0) {
return -1;
}
return 0;
}
void NetworkDisconnect(Network* n)
{
hal_itls_destroy(n->handle);
}
CMakeLists.txt - 鏈接ID2靜態(tài)庫(kù):
file(GLOB SOURCES "*.c" "linux/*.c")
add_library(
paho-embed-mqtt3cc SHARED
${SOURCES}
)
install(TARGETS paho-embed-mqtt3cc DESTINATION /usr/lib)
add_library(libitls STATIC IMPORTED)
set_target_properties(libitls PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libitls.a)
add_library(libid2 STATIC IMPORTED)
set_target_properties(libid2 PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libid2.a)
add_library(libicrypt STATIC IMPORTED)
set_target_properties(libicrypt PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libicrypt.a)
add_library(libkm STATIC IMPORTED)
set_target_properties(libkm PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libkm.a)
add_library(libls_hal STATIC IMPORTED)
set_target_properties(libls_hal PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libls_hal.a)
add_library(libls_osa STATIC IMPORTED)
set_target_properties(libls_osa PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/linux/libs/libls_osa.a)
target_link_libraries(paho-embed-mqtt3cc libitls libid2 libicrypt libkm libls_hal libls_osa)
target_link_libraries(paho-embed-mqtt3cc rt pthread)
target_include_directories(paho-embed-mqtt3cc PRIVATE "linux" "linux/include/itls")
target_link_libraries(paho-embed-mqtt3cc paho-embed-mqtt3c)
target_compile_definitions(paho-embed-mqtt3cc PRIVATE
MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h MQTTCLIENT_QOS2=1)
第三步:Paho通過(guò)ID2連接LP的示例 - MQTTClient-C/samples:
linux/aiot_id2_demo.c示例代碼:
#include "MQTTClient.h"
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#define EXAMPLE_PRODUCT_KEY "xxxxxxx"
#define EXAMPLE_PRODUCT_SECRET "xxxxxxx"
#define EXAMPLE_DEVICE_NAME "Paho_ID2_Device_1"
#define EXAMPLE_DEVICE_SECRET "b21bc6147266242838d06ff50c00d0ab"
#if !defined(CONFIG_LP_INSTANCED)
#define MQTT_CLINETID_KV "|securemode=8,signmethod=hmacsha1,timestamp=2524608000000,authtype=id2|"
#else
#define MQTT_CLINETID_KV "|securemode=8,signmethod=hmacsha1,timestamp=2524608000000,authtype=id2,instanceId=xxxxx|"
#endif
#define PRODUCTKEY_MAXLEN (20)
#define DEVICENAME_MAXLEN (32)
#define DEVICESECRET_MAXLEN (64)
#define USERNAME_MAXLEN (64)
#define PASSWORD_MAXLEN (65)
int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret,
char clientId[150], char username[64], char password[65])
{
char deviceId[PRODUCTKEY_MAXLEN + DEVICENAME_MAXLEN + 2] = {0};
/* setup deviceId */
memcpy(deviceId, deviceName, strlen(deviceName));
memcpy(deviceId + strlen(deviceId), "&", strlen("&"));
memcpy(deviceId + strlen(deviceId), productKey, strlen(productKey));
/* setup clientid */
memcpy(clientId, deviceId, strlen(deviceId));
memcpy(clientId + strlen(deviceId), MQTT_CLINETID_KV, strlen(MQTT_CLINETID_KV));
memset(clientId + strlen(deviceId) + strlen(MQTT_CLINETID_KV), 0, 1);
/* setup username */
memcpy(username, deviceId, strlen(deviceId));
memset(username + strlen(deviceId), 0, 1);
/* setup password */
memset(password, '0', PASSWORD_MAXLEN - 1);
memcpy(password, "FFFFFFFFFFFFFFFF1234567812345678", 32);
return 0;
}
volatile int toStop = 0;
void cfinish(int sig)
{
signal(SIGINT, NULL);
toStop = 1;
}
void messageArrived(MessageData* md)
{
MQTTMessage* message = md->message;
printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data);
printf("%.*s\n", (int)message->payloadlen, (char*)message->payload);
}
/* main function */
int main(int argc, char** argv)
{
int rc = 0;
/* setup the buffer, it must big enough for aliyun IoT platform */
unsigned char buf[1000];
unsigned char readbuf[1000];
Network n;
MQTTClient c;
char *host = EXAMPLE_PRODUCT_KEY".itls.cn-shanghai.aliyuncs.com";
short port = 1883;
const char *subTopic = "/"EXAMPLE_PRODUCT_KEY"/"EXAMPLE_DEVICE_NAME"/user/get";
const char *pubTopic = "/"EXAMPLE_PRODUCT_KEY"/"EXAMPLE_DEVICE_NAME"/user/update";
/* invoke aiotMqttSign to generate mqtt connect parameters */
char clientId[150] = {0};
char username[65] = {0};
char password[65] = {0};
if ((rc = aiotMqttSign(EXAMPLE_PRODUCT_KEY, EXAMPLE_DEVICE_NAME,
EXAMPLE_DEVICE_SECRET, clientId, username, password) < 0)) {
printf("aiotMqttSign -%0x4x\n", -rc);
return -1;
}
printf("clientid: %s\n", clientId);
printf("username: %s\n", username);
printf("password: %s\n", password);
signal(SIGINT, cfinish);
signal(SIGTERM, cfinish);
/* network init and establish network to aliyun IoT platform */
NetworkInit(&n);
NetworkSetConfig(&n, EXAMPLE_PRODUCT_KEY, EXAMPLE_PRODUCT_SECRET);
rc = NetworkConnect(&n, host, port);
if (rc < 0) {
printf("NetworkConnect %d\n", rc);
return -1;
}
/* init mqtt client */
MQTTClientInit(&c, &n, 1000, buf, sizeof(buf), readbuf, sizeof(readbuf));
/* set the default message handler */
c.defaultMessageHandler = messageArrived;
/* set mqtt connect parameter */
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.willFlag = 0;
data.MQTTVersion = 3;
data.clientID.cstring = clientId;
data.username.cstring = username;
data.password.cstring = password;
data.keepAliveInterval = 60;
data.cleansession = 1;
printf("Connecting to %s %d\n", host, port);
rc = MQTTConnect(&c, &data);
if (rc < 0) {
printf("MQTTConnect fail %d!\n", rc);
return -1;
} else {
printf("MQTTConnect %d, Connect aliyun IoT Cloud Success!\n", rc);
}
printf("Subscribing to %s\n", subTopic);
rc = MQTTSubscribe(&c, subTopic, 1, messageArrived);
printf("MQTTSubscribe %d\n", rc);
int cnt = 0;
unsigned int msgid = 0;
while (!toStop)
{
MQTTYield(&c, 1000);
if (++cnt % 5 == 0) {
MQTTMessage msg = {
QOS1, 0, 0, 0, "Hello world", strlen("Hello world"),
};
msg.id = ++msgid;
rc = MQTTPublish(&c, pubTopic, &msg);
printf("MQTTPublish %d, msgid %d\n", rc, msgid);
}
}
printf("Stopping\n");
MQTTDisconnect(&c);
NetworkDisconnect(&n);
return 0;
}
更新如下的信息:
EXAMPLE_PRODUCT_KEY:填寫阿里云物聯(lián)網(wǎng)平臺(tái)(LP)產(chǎn)品標(biāo)識(shí),在創(chuàng)建時(shí)需選擇“ID2認(rèn)證”
EXAMPLE_PRODUCT_SECRET:填寫阿里云物聯(lián)網(wǎng)平臺(tái)(LP)產(chǎn)品密鑰,在產(chǎn)品創(chuàng)建控制臺(tái)查詢
EXAMPLE_DEVICE_NAME:填寫設(shè)備標(biāo)識(shí),產(chǎn)品維度內(nèi)唯一
EXAMPLE_DEVICE_SECRET:填寫設(shè)備密鑰,選擇“ID2認(rèn)證”時(shí),可以使用任意字符串
選擇正確的MQTT_CLINETID_KV:ClientId的鍵值信息
LP公共實(shí)例:
deviceId+"|securemode=8,signmethod=hmacsha1,timestamp=2524608000000,authtype=id2|"
LP企業(yè)實(shí)例:
"|securemode=8,signmethod=hmacsha1,timestamp=2524608000000,authtype=id2,instanceId=xxxxx|", 其中instanceId為企業(yè)實(shí)例ID(登錄物聯(lián)網(wǎng)平臺(tái)控制臺(tái),在實(shí)例概覽頁(yè)面查看)
LP平臺(tái)的域名和端口號(hào):
host:${YourProductKey}.itls.cn-shanghai.aliyuncs.com,其中${YourProductKey}為申請(qǐng)的產(chǎn)品標(biāo)識(shí)
port:1883
CMakeLists.txt - 編譯腳本:
add_executable(
stdoutsubc
stdoutsub.c
)
target_link_libraries(stdoutsubc paho-embed-mqtt3cc paho-embed-mqtt3c)
target_include_directories(stdoutsubc PRIVATE "../../src" "../../src/linux")
target_compile_definitions(stdoutsubc PRIVATE MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h)
add_executable(
aiot_id2_demo
aiot_id2_demo.c
)
target_link_libraries(aiot_id2_demo paho-embed-mqtt3cc paho-embed-mqtt3c)
target_include_directories(aiot_id2_demo PRIVATE "../../src" "../../src/linux" "./include/osa")
target_compile_definitions(aiot_id2_demo PRIVATE MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h)
第四步:固件編譯:
paho.mqtt.embedded-c根目錄,創(chuàng)建build.paho編譯目錄
到build.paho目錄,運(yùn)行"cmake & make"進(jìn)行編譯
編譯成功,ID2固件生成在build.paho/MQTTClient-C/samples/linux目錄
第五步:固件運(yùn)行:
正確運(yùn)行aiot_id2_demo,可得到如下日志:
3.5 調(diào)試驗(yàn)證:
ID2建連錯(cuò)誤調(diào)試:
ID2-iTLS建連失敗時(shí),首先可以通過(guò)查看消息警告(alert message)進(jìn)行問(wèn)題排查:
上面的消息警告中,2 - FATAL類型的警告;172 - 消息警告類型,ID2-iTLS常見的錯(cuò)誤警告類型如下:
錯(cuò)誤碼 | 錯(cuò)誤信息 | 評(píng)論 |
160 | ID2 generic error | 通用錯(cuò)誤,檢查Product Secret是否正確 |
161 | ID2 no quota | ID2配額不足,需先購(gòu)買ID2 |
162 | ID2 is not exist | 服務(wù)端識(shí)別不了此ID2,可刪除設(shè)備上ID2(如KM載體)后,重新空發(fā)ID2 |
163 | ID2 authcode is invalid | ID2認(rèn)證碼錯(cuò)誤,校驗(yàn)挑戰(zhàn)字是否有效(ID2服務(wù)端申請(qǐng)&只使用一次) |
164 | ID2 has not been activated | ID2已經(jīng)激活 |
165 | The timestamp used in authcode is expired | 檢查設(shè)備端時(shí)間是否同步 |
166 | ID2 challenge is invalid | ID2認(rèn)證碼中,挑戰(zhàn)字非法(挑戰(zhàn)字模式) |
167 | Not support this operation | 不支持此操作 |
168 | ID2 has been suspended | ID2已暫停使用 |
169 | ID2 has been discarded | ID2已廢棄 |
170 | Permission denied, id2 has been blinded to other product key | ID2已綁定到其他產(chǎn)品,不容許在該產(chǎn)品使用;改回綁定的產(chǎn)品,或者刪除設(shè)備上的ID2,再重新空發(fā)一個(gè)新的ID2 |
171 | Product key is invalid | ID2產(chǎn)品非法,如已廢棄 |
172 | Product key is not exist | ID2產(chǎn)品不存在,產(chǎn)品錯(cuò)誤填入,或者申請(qǐng)產(chǎn)品時(shí),沒(méi)有選擇"ID2認(rèn)證" |
ID2設(shè)備上線驗(yàn)證:
設(shè)備端ID2-iTLS建連成功后,在物聯(lián)網(wǎng)管理平臺(tái),可看到新創(chuàng)建的設(shè)備和設(shè)備的上線信息。
在左側(cè)導(dǎo)航欄,選擇設(shè)備管理 > 設(shè)備,DeviceName是ID2示例中設(shè)置的設(shè)備證書(ProductKey、DeviceName、DeviceSecret)設(shè)備名。
登錄IoT安全中心。
在左側(cè)導(dǎo)航欄,選擇物聯(lián)網(wǎng)身份 > 設(shè)備身份認(rèn)證,查看通過(guò)ID2激活的設(shè)備信息。