使用ID2-KM將設(shè)備接入自建的物聯(lián)網(wǎng)系統(tǒng)
本文介紹了設(shè)備如何通過更安全的身份認(rèn)證方式(ID2)連接到您自建的物聯(lián)網(wǎng)系統(tǒng)(設(shè)備管理平臺)。
1. 術(shù)語
Soft-KM(Key Management)密鑰管理,由阿里提供的軟件安全沙箱,基于軟件加固和虛擬化技術(shù)提供對密鑰(IoT ID2)的安全保護(hù)。
OSA(Operation System Abstractor Layer)操作系統(tǒng)抽象層,定義內(nèi)存申請和釋放、日志打印、系統(tǒng)時間、網(wǎng)絡(luò)通信等接口,非遵循POSIX標(biāo)準(zhǔn)的OS,需重新適配這些接口。
HAL(Hardware Abstractor Layer)硬件抽象層,根據(jù)設(shè)備硬件特性,完成對加解密算法、設(shè)備唯一ID、密鑰管理和數(shù)據(jù)安全存儲的接口適配。
ID2 OTP(One-Time Provisioning)一次性燒錄,也稱ID2空發(fā),指設(shè)備在第一次聯(lián)網(wǎng)時,通過網(wǎng)絡(luò)請求,下發(fā)ID2數(shù)據(jù)燒錄到設(shè)備中。
TLS(Transport Layer Security)安全傳輸層協(xié)議, 用于兩個通信實體之間,保護(hù)通信數(shù)據(jù)的私密性和完整性。
IoT(Internet of things)物聯(lián)網(wǎng),基于互聯(lián)網(wǎng)實現(xiàn)萬物互聯(lián)。
2. ID2產(chǎn)品架構(gòu)
ID2控制中心:
ID2的Web控制臺,提供對ID2產(chǎn)線灌裝、ID2產(chǎn)品和配額申請、以及ID2使用統(tǒng)計的管理。
ID2服務(wù)中心:
ID2在云端的應(yīng)用,提供ID2的各種安全能力,包括ID2密鑰安全分發(fā)、設(shè)備認(rèn)證、基于ID2的安全連接協(xié)議等;同時,提供各種能力的云端接口,支持業(yè)務(wù)平臺的二次開發(fā),支持不同的安全業(yè)務(wù)需求和場景。
ID2 Client SDK(ID2設(shè)備端SDK):
ID2在設(shè)備端的功能組件和軟件開發(fā)框架,可支持不同操作系統(tǒng)和不同硬件,為IoT設(shè)備提供基于ID2的端到端的設(shè)備認(rèn)證、數(shù)據(jù)加解密等各種安全能力。
3. ID2接入流程
3.1 概述
客戶自建服務(wù)的方式,ID2通過云端和設(shè)備端接口的方式,提供基于ID2的設(shè)備認(rèn)證和會話密鑰加密下發(fā),應(yīng)用數(shù)據(jù)通過下發(fā)的會話密鑰進(jìn)行加密傳輸。
ID2對接步驟如下:
3.2 購買ID2授權(quán):
單機(jī)購買鏈接 - 購買ID2認(rèn)證授權(quán)。
選擇地域和可用區(qū)、規(guī)格、購買數(shù)量和有效期:
3.3 創(chuàng)建產(chǎn)品:
登錄IoT安全產(chǎn)品控制臺控制臺,在左側(cè)導(dǎo)航欄,選擇入門 > IoT設(shè)備身份認(rèn)證,單擊獨立使用卡片的開始接入按鈕。
在配置產(chǎn)品頁面創(chuàng)建新產(chǎn)品&分配ID2授權(quán),然后單擊下一步按鈕。
選擇產(chǎn)品:請選擇創(chuàng)建新產(chǎn)品,并輸入產(chǎn)品名稱。
ID2有效期:請選擇1年、3年、或5年。
分配ID2授權(quán)數(shù)量:請輸入ID2授權(quán)數(shù)量,最小值為1,最大值為1000。
在查看配置信息頁面,記錄下ProductKey、ProductSecret。
ProductKey:設(shè)備所屬產(chǎn)品的ProductKey。
ProductSecret:由IoT設(shè)備身份認(rèn)證頒發(fā)的產(chǎn)品密鑰,與 ProductKey 成對出現(xiàn)。
3.4 選擇設(shè)備認(rèn)證算法:
IoT設(shè)備身份認(rèn)證支持國際算法(AES-128、AES-192、AES-256)和國密算法(SM1、SM2、SM4-128),能滿足企業(yè)不同安全等級的需求。
說明
國密算法SM1需要配合ID2安全芯片使用,SM2用于業(yè)務(wù)數(shù)據(jù)完整性校驗和加密。
創(chuàng)建的ID2產(chǎn)品默認(rèn)選擇的設(shè)備認(rèn)證算法是AES-128;如需選擇其他設(shè)備認(rèn)證算法,請按如下步驟操作:
在查看配置信息頁面,單擊設(shè)備認(rèn)證算法后的更換按鈕,查看支持的密鑰類型(如SM4-128),并確認(rèn)。
在查看配置信息頁面,記錄下實例ID、ProductKey、ProductSecret。
實例ID:阿里云物聯(lián)網(wǎng)平臺的實例標(biāo)識。企業(yè)實例ID是字符串,公共實例ID是符號“-”。
ProductKey:設(shè)備所屬產(chǎn)品的ProductKey。
ProductSecret:由IoT設(shè)備身份認(rèn)證頒發(fā)的產(chǎn)品密鑰,與 ProductKey 成對出現(xiàn)
3.5 集成云端SDK
3.5.1 阿里云賬號的AccessKey
AccessKey是調(diào)用阿里云API的身份憑證,請參見獲取AccessKey。
需要注意的是AccessKey的歸屬賬號必須與創(chuàng)建產(chǎn)品時的賬號保持一致。
3.5.2 下載云端SDK
登錄IoT安全產(chǎn)品控制臺控制臺,在左側(cè)導(dǎo)航欄,選擇文檔與工具,在IoT設(shè)備身份認(rèn)證云端SDK中單擊立即下載右側(cè)的復(fù)制按鈕獲取最新的下載地址,在云端環(huán)境執(zhí)行命令獲取云端SDK。
wget https://id2-schip-online.oss-cn-shanghai.aliyuncs.com/static_resources/id2_server_sdk/ID2_Server_SDK.tar
在云端環(huán)境執(zhí)行命令tar -xvf ID2_Server_SDK.tar 完成解壓,執(zhí)行命令cd <解壓SDK后的目錄>。設(shè)備端SDK的目錄說明見表格內(nèi)容:
目錄/文件 | 說明 |
demos | ID2云端的示例代碼 |
lib | ID2云端的Jar包 |
3.5.3 集成云端SDK
添加Maven項目依賴,引入阿里云Java SDK公共包。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.6</version>
</dependency>
導(dǎo)入云端SDK中的lib/aliyun-java-sdk-id2-1.1.4.jar到項目工程中,初始化云端SDK。
public static String ACCESS_KEY = null;
public static String ACCESS_SECRET = null;
public static String REGION_ID = "cn-shanghai";
public static String END_POINT = "id2." + REGION_ID + ".aliyuncs.com";
// Load ACCESS_KEY and ACCESS_SECRET From Config File
loadConfigProperties("xxx.conf");
IClientProfile profile = DefaultProfile.getProfile(REGION_ID, ACCESS_KEY, ACCESS_SECRET);
DefaultProfile.addEndpoint(REGION_ID, PRODUCT_CODE, END_POINT);
client = new DefaultAcsClient(profile);
發(fā)起調(diào)用,ID2云端SDK為每個API封裝了一個類,命名為${API名稱}+"Request",如VerifyRequest,用于API的調(diào)用請求,ID2云端API列表請參考服務(wù)端API。
ID2空發(fā)
OtpGetId2Request request = new OtpGetId2Request();
request.setDeviceAuthCode(authCode);
request.setApiVersion(1.1.2);
OtpGetId2Response response = client.getAcsResponse(request);
獲取ID2認(rèn)證挑戰(zhàn)字
GetServerRandomRequest request = new GetServerRandomRequest();
request.setId2(id2Id);
request.setApiVersion(1.1.2);
GetServerRandomResponse response = client.getAcsResponse(request);
System.out.println("GetServerRadom requestId:" + response.getRequestId());
ID2設(shè)備認(rèn)證和業(yè)務(wù)密鑰加密
VerifyAndEncryptRequest request = new VerifyAndEncryptRequest();
request.setApiVersion(1.1.2);
request.setProductKey(productKey);
request.setId2(id2Id);
request.setAuthCode(authCode);
request.setData(keyInfo);
VerifyAndEncryptResponse response = client.getAcsResponse(request);
System.out.println("VerifyAndEncrypt requestId:" + response.getRequestId());
應(yīng)用集成ID2云端SDK的示例代碼,請參考demos/ID2SPMessage
3.6 集成設(shè)備端SDK:
3.6.1 ID2設(shè)備端SDK框架:
iTLS:輕量的安全連接協(xié)議TLS,基于ID2完成TLS的握手認(rèn)證和密鑰協(xié)議,提供應(yīng)用數(shù)據(jù)的加密傳輸。
ID2:IoT設(shè)備認(rèn)證和數(shù)據(jù)加密的對外接口,上層應(yīng)用/協(xié)議基于此接口進(jìn)行開發(fā)。
KM:密鑰管理模塊,支持不同形式的載體:
Soft-KM:軟件沙箱,基于軟件加固和虛擬化技術(shù)提供對ID2密鑰的安全保護(hù)。
SE(Secure Element):安全芯片,基于物理防護(hù)機(jī)制,提供對ID2密鑰的安全保護(hù),通過AT指令對設(shè)備提供ID2的運(yùn)算指令。
Crypto:提供統(tǒng)一的加解密算法接口。
OSA:操作系統(tǒng)適配接口,廠商需根據(jù)使用的OS,重新進(jìn)行接口適配。
HAL:硬件適配接口,提供算法庫和Soft-KM的適配接口,廠商需根據(jù)選擇的硬件平臺,重新進(jìn)行接口適配。
3.6.2 下載設(shè)備端SDK:
登錄IoT安全產(chǎn)品控制臺,在左側(cè)導(dǎo)航欄,選擇文檔與工具,在IoT設(shè)備身份認(rèn)證設(shè)備端SDK中單擊立即下載右側(cè)的復(fù)制按鈕獲取最新的下載地址,執(zhí)行命令獲取設(shè)備端SDK。
wget https://id2-schip-online.oss-cn-shanghai.aliyuncs.com/static_resources/id2_client_sdk/ID2_Client_SDK.tar
執(zhí)行命令tar -xvf ID2_Client_SDK.tar完成解壓,執(zhí)行命令cd <解壓SDK后的目錄>。設(shè)備端SDK的目錄說明見表格內(nèi)容:
目錄/文件 | 說明 |
demos | ID2設(shè)備端的示例代碼:
|
external | 用于存放外部的組件:
|
include | ID2的頭文件目錄 |
libs | ID2的靜態(tài)庫 |
make.rules | 編譯規(guī)則文件,可配置編譯工具鏈和編譯參數(shù) |
make.settings | 編譯配置文件,可配置ID2的密鑰類型(如AES、SM4) |
makefile | 編譯腳本 |
src | ID2的源碼目錄 |
tests | ID2的測試用例,包括HAL和ID2的測試。 |
3.6.3 集成設(shè)備端SDK:
調(diào)用設(shè)備端ID2的接口,完成ID2空發(fā),ID2設(shè)備認(rèn)證和數(shù)據(jù)加密等功能,工作原理圖如下:
ID2空發(fā):
通過ID2產(chǎn)品的ProductSecret,生成ID2的空發(fā)認(rèn)證碼(AuthCode),發(fā)送到云端調(diào)用ID2服務(wù)端的接口,完成ID2的申請和下發(fā)
ID2設(shè)備認(rèn)證和數(shù)據(jù)加密:
基于挑戰(zhàn)字認(rèn)證方式,通過在設(shè)備端調(diào)用ID2 SDK生成ID2的設(shè)備認(rèn)證碼,發(fā)送到云端調(diào)用ID2的云端SDK,完成ID2的設(shè)備認(rèn)證和會話密鑰的加密;然后,在設(shè)備端調(diào)用ID2 SDK的解密接口,完成會話密鑰的解密
使用自有的應(yīng)用,完成如下的集成工作:
設(shè)備硬件及系統(tǒng)層集成,詳情請參考ID2安全Agent適配接口
OSA接口適配:實現(xiàn)src/osa/ls_osa.c中的接口,參考目錄下__DEMO__的實現(xiàn)。
HAL接口適配:實現(xiàn)src/hal/km/demo/ls_hal_km.c中的接口,通過hal_test測試用例驗證(成功日志: “HAL KM Test Pass”),參考目錄下__DEMO__的實現(xiàn)。
設(shè)備應(yīng)用層集成,詳情請參考設(shè)備端API
設(shè)備應(yīng)用首先調(diào)用ID2的初始化函數(shù),完成設(shè)備端SDK的初始化。
{
int ret;
ret = id2_client_init();
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client init fail, %d\n", ret);
return -1;
}
}
獲取ID2設(shè)備端的燒錄狀態(tài):
如ID2已燒錄(is_prov == true),退出ID2空發(fā)流程
{
int ret = 0;
bool is_prov = false;
ret = id2_client_get_prov_stat(&is_prov);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client get prov stat fail, %d\n", ret);
return -1;
}
}
生成ID2設(shè)備端的空發(fā)認(rèn)證碼。
{
int ret = 0;
uint8_t auth_code[ID2_MAX_AUTH_CODE_LEN] = {0};
uint32_t auth_code_len = ID2_MAX_AUTH_CODE_LEN;
ret = id2_client_get_otp_auth_code(
(uint8_t *)product_secret, (int)strlen(product_secret),
auth_code, &auth_code_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2_client_get_otp_auth_code fail, %d\n", ret);
return -1;
}
}
ID2空發(fā)的網(wǎng)絡(luò)請求和響應(yīng)。
authCode:ID2空發(fā)認(rèn)證碼的Base64編碼
otpData:ID2云端下發(fā)的空發(fā)數(shù)據(jù)(Base64格式)
# ID2空發(fā)請求:
{commandId:xxx, authCode: xxx}
# ID2空發(fā)響應(yīng):
{commandId:xxx, otpData: xxx}
存儲ID2密鑰到設(shè)備安全存儲區(qū)。
{
int ret = 0;
ret = id2_client_load_otp_data(otp_data, otp_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 load otp data fail, %d\n", ret);
return -1;
}
}
獲取設(shè)備端的ID2 ID。
{
int ret = 0;
uint8_t id2_id[ID2_ID_MAX_LEN + 1] = {0};
uint32_t id2_id_len = ID2_ID_MAX_LEN;
ret = id2_client_get_id(id2_id, &id2_id_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client get id fail, %d\n", ret);
return -1;
}
}{
int ret = 0;
uint8_t id2_id[ID2_ID_MAX_LEN + 1] = {0};
uint32_t id2_id_len = ID2_ID_MAX_LEN;
ret = id2_client_get_id(id2_id, &id2_id_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client get id fail, %d\n", ret);
return -1;
}
}
ID2認(rèn)證挑戰(zhàn)字的網(wǎng)絡(luò)請求和響應(yīng)。
# ID2認(rèn)證挑戰(zhàn)字的請求:
{commandId:xxx, Id2Id: xxx}
# ID2認(rèn)證挑戰(zhàn)字的響應(yīng):
{commandId:xxx, challenge: xxx}
獲取設(shè)備端的ID2認(rèn)證碼。
{
int ret = 0;
uint8_t auth_code[ID2_MAX_AUTH_CODE_LEN] = {0};
uint32_t auth_code_len = ID2_MAX_AUTH_CODE_LEN;
ret = id2_client_get_challenge_auth_code(
challenge, NULL, 0, auth_code, &auth_code_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client get challenge auth code fail, %d\n", ret);
return -1;
}
}
設(shè)備端認(rèn)證和數(shù)據(jù)加密的網(wǎng)絡(luò)請求和響應(yīng)。
cipherData:ID2云端下發(fā)的加密數(shù)據(jù)
# ID2設(shè)備認(rèn)證和數(shù)據(jù)加密的請求:
{commandId:xxx, productKey:xxx, Id2Id:xxx, authCode:xxx}
# ID2設(shè)備認(rèn)證和數(shù)據(jù)加密的響應(yīng):
{commandId:xxx, cipherData: xxx}
解密ID2云端加密下發(fā)的數(shù)據(jù)。
{
int ret = 0;
ret = id2_client_decrypt(cipher_data, cipher_len, cipher_data, &cipher_len);
if (ret != IROT_SUCCESS) {
ls_osa_print("id2 client decrypt fail\n");
return -1;
}
}
應(yīng)用集成ID2設(shè)備SDK的示例代碼,請參考demos/spdemo
設(shè)備端SDK的編譯:
在ID2 SDK的根目錄,執(zhí)行命令vi ./make.settings打開文件, 修改CONFIG_LS_ID2_KEY_TYPE的值
同ID2產(chǎn)品選擇的認(rèn)證算法保持相同
執(zhí)行命令“make clean & make plat=xxx”進(jìn)行編譯
Linux x86_64默認(rèn)使用系統(tǒng)中的GCC作為編譯工具,且默認(rèn)指定“plat=x86_64”參數(shù)
如要編譯其他架構(gòu),如armhf,在make.rules中配置編譯工具,運(yùn)行編譯命令“make clean & make plat=armhf”
3.7 業(yè)務(wù)數(shù)據(jù)加密
方式一:運(yùn)行設(shè)備端自有的應(yīng)用和自建的SP Server,進(jìn)行ID2認(rèn)證和加密,以及業(yè)務(wù)數(shù)據(jù)加密的調(diào)試。
方式二:使用演示示例:
部署EMQX物聯(lián)網(wǎng)平臺,詳情參見EMQX安裝和部署
本節(jié)描述在Ubuntu 22.04上通過Docker部署EMQX物聯(lián)網(wǎng)平臺的示例
安裝和啟動Docker工具:
# Install Docker
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
# Start Docker
sudo systemctl enable docker
sudo systemctl start docker
# Get Docker Version
docker -v
使用Docker安裝EMQX物聯(lián)網(wǎng)平臺:
# Get emqx-5.1.3 docker image
docker pull emqx/emqx:5.1.3
# Start docker emqx instance
docker run -d --name emqx -p 1883:1883 emqx/emqx:5.1.3
# Get docker instance info
docker ps
部署云端演示示例,在ID2云端SDK根目錄,配置vi demos/ID2SPMessage/Id2SpDemo.conf文件中的AccessKey和AccessSecret信息。
執(zhí)行命令cd demos/ID2SPMessage,執(zhí)行命令java -jar Id2SpDemo.jar啟動云端演示示例。
在ID2設(shè)備端SDK目錄,執(zhí)行命令vi tools/ls_sp_demo.sh填寫如下參數(shù):
HostAddr:云端演示示例的IP地址,localhost代表本機(jī)網(wǎng)絡(luò)。
ProductKey:ID2產(chǎn)品的ProductKey。
ProductSecret:ID2產(chǎn)品的ProductSecret。
PublishData:設(shè)備端應(yīng)用上報的業(yè)務(wù)數(shù)據(jù),建議不超過1024字節(jié)。
執(zhí)行命令./tools/ls_sp_demo.sh運(yùn)行設(shè)備端演示示例,查看設(shè)備端打印的日志。
在設(shè)備端日志中,可以看到完成ID2的設(shè)備認(rèn)證,以及通過ID2加密下發(fā)SP Key Info;設(shè)備端通過ID2設(shè)備端接口解密后,獲得明文的Key ID和Data
在設(shè)備端日志中,可看到由SPKey加密下發(fā)的業(yè)務(wù)數(shù)據(jù)(“SP Server Subscribed Cipher Data”);通過在調(diào)用SPKey解密后,可得到明文的下行業(yè)務(wù)數(shù)據(jù)(“SP_Server_Hello”)
在云端查看打印的日志。
可看到由SPKey加密的業(yè)務(wù)數(shù)據(jù)("Device Published Cipher Data")
使用SPKey解密后,可得到正確的上行業(yè)務(wù)數(shù)據(jù)(“SP_Client_Hello”)
查看設(shè)備狀態(tài):
登錄產(chǎn)品控制臺,在左側(cè)導(dǎo)航欄,選擇資產(chǎn)>設(shè)備,查看設(shè)備狀態(tài)為正常,安全狀態(tài)為安全。