1. 簡介
AI算法保護,提供內容的加密保護和全生命周期管理;授權過程的自動化和授權管理的統一化,防止內容的拷貝和泄漏,以及提供商業售賣的靈活性、安全性和管理成本。
內容加密保護,一次性加密,多種許可分發和管理,支持不同的授權管理策略,滿足不同場景的需求。
基于IoT安全自建的設備認證產品(ID2),為內容保護提供全鏈路的安全保護。
本文說明基于客戶物聯網平臺提供的消息傳輸通道,使用AI算法保護,進行內容的加密保護和授權管理。
2. 角色劃分
接入AI算法保護會劃分為兩類角色,廠商需要根據不同的角色按步驟接入。
?
算法廠商:擁有AI算法的核心能力,在業務場景中會把算法授權到其它設備廠商使用。
設備廠商:擁有自己的IoT設備,計劃在IoT設備使用算法廠商所提供的算法。
3. 對接流程
3.1 整體接入流程
3.2 算法廠商接入
3.2.1 服務開通(線下)
通過IoT安全中心官網AI算法保護模塊,聯系我們進行線下開通。
3.2.2 模型加密(離線)
加密工具下載:服務開通后,通過點擊AI算法保護-算法模型-離線加密工具,下載加密工具到本地,對原始的模型進行處理。
模型加密工具:content_packager(Release Package/tools目錄),運行在Ubuntu的可執行程序。
模型加密工具 - 選項說明:
參數 (均為string類型) | 說明 | 附注 |
--help | 打印該使用說明 | |
--version | 打印內容打包工具的版本 | |
--input | 待保護的文件 | 通過格式判定 |
--license | 支持2種情況:
|
|
--config | 保護配置文件(.json) | 用于配置模型文件的加密方式 |
--company | 公司名稱 | 長度在4~8之間 |
授權配置文件:
打開license配置文件模板license_config.json,配置如下參數:
參數 | 類型 | 說明 |
license_id | string |
|
extras | string | 用戶數據,最長256 字節,超過會截斷。 |
machine | string | 授權的設備id, 空則不綁定 |
valid_count | uint32 | 有效使用次數(-1 則無限制) |
valid_period_days | uint32 | 有效使用天數(-1 則無限制) |
?
保護配置文件:
打開保護配置文件模板protect_config.json,配置如下參數:
參數 | 類型 | 說明 |
enc_type | string | 加密保護的內容類型:
|
enc_model | bool | true :打開分層加密 false:關閉分層加密(不改造算法模型) |
max_size | float | 最大加密的數據量(單位:MB):
|
sec_level | uint32 | 模型加密的安全強度(Security Level): 0 - 標準的AES加密 1 - 輕量的AES加密 |
模型加密工具 - 使用示例:
授權配置文件 - license_info.json,保護配置文件 - protect_config.json,模型文件 - googlenet.caffemodel:
./content_packager --input googlenet.caffemodel --license license_info.json --config protect_config.json --company alibaba |
輸出如下:
<PACK_TOOL> version: 1.2.0 <PACK_TOOL> folder ./LD-0100-alibaba-2944-20210104095107 is created <PACK_TOOL> License: ./LD-0100-alibaba-2944-20210104095107/LD-0100-alibaba-2944-20210104095107.lic <PACK_TOOL> Encrypted Content: ./LD-0100-alibaba-2944-20210104095107/googlenet.caffemodel.enc <PACK_TOOL> Content Packager Finished |
生成的加密文件為 <原始文件名稱>.enc,License文件為 <license id>.lic 存放在以licence id命名的文件夾中。
3.2.3 算法模型創建
如果算法廠商準備授權一種新的算法到設備廠商,首先需要對模型進行離線加密處理,然后完成算法模型創建。
點擊新增算法模型按鈕,會彈出新增算法模型窗口。
輸入算法廠商名稱和算法模型名稱。
上傳授權許可文件,該文件由離線加密工具輸出<license_id>.lic。
點擊確認按鈕完成算法模型新增。
3.2.4 設備廠商授權
?
算法廠商首先完成算法模型創建,然后通過此步驟把算法授權到設備廠商。完成該步驟后,設備廠商擁有使用該算法的權限,設備廠商可以按照設備廠商角色相關步驟進行后續的接入操作。
請點擊新增授權按鈕,彈出新增授權窗口。
輸入授權名稱、設備廠商阿里云賬號UID,所關聯的算法模型。(請確保輸入有效的設備廠商阿里云賬號UID)
指定產品使用的授權配額,允許設備廠商特定數量的IoT設備使用所關聯的算法模型。
指定AI算法授權到期時間。(當AI算法到期后,IoT設備不能再使用所關聯的算法模型)
配置最大離線時間,(0~10000)小時,0表示允許永久離線。(當離線間隔到期后,IoT設備需要聯網更新才能繼續使用)
點擊確認按鈕完成授權新增。
3.2.5 查看使用記錄
請點擊AI算法保護-使用記錄,可查看設備廠商的IoT設備連接云端平臺獲取授權的使用記錄信息。
數據總覽界面。
已購買授權:表示算法廠商購買的授權總額度。
已分配:表示算法廠商已經分配到設備廠商的授權額度。
已使用:表示算法廠商所授權的設備廠商已使用的授權數量。
AI算法模型:表示算法廠商所創建的算法模型數量。
3.3 設備廠商接入
3.3.1 服務開通?
請聯系提供AI算法的算法廠商,并把自己阿里云賬號UID提供到算法廠商,由算法廠商為其進行授權。
當算法廠商授權完成后,設備廠商可以登錄IoT安全中心 AI算法保護模塊,查看算法授權信息。包括算法廠商名稱,算法模型名稱,LicenseID,授權有效期,以及授權額度等信息。
3.3.2 創建產品
點擊資產管理-直連設備-創建產品按鈕,彈出創建產品的窗口,選擇我有自己的設備管理系統,只需要使用“物聯網身份-設備身份認證”的能力。
輸入產品名稱,選擇使用的密鑰類型。
點擊提交按鈕完成產品創建。
3.2.3 關聯產品
?
設備廠商首先完成產品創建,并記錄產品的productKey信息,通過此步驟完成算法授權和產品的關聯。完成該操作后,允許該產品下指定授權數量的IoT設備可以使用算法廠商所提供的算法。
選擇需要進行關聯的授權記錄,點擊關聯產品。
輸入需要關聯的產品ProductKey,如果還沒完成產品創建請先完成產品創建。
點擊確認按鈕完成產品關聯。
3.2.4 服務端對接
3.2.4.1 授權消息格式:
通過物聯網傳輸通道,在應用協議(如MQTT、HTTP)中增加特定的消息類型,標識上行和下行的授權消息。
上行授權消息,需包含的字段:
productKey:產品標識,字符串。
payload:設備授權請求數據,Base64格式。
下行授權消息,需包含的字段:
status:服務端POP接口的結果。
payload:設備授權響應數據,Bae64格式。
3.2.4.2 授權消息轉發:
物聯網平臺,收到設備上報的授權消息請求時,調用授權POP接口,完成授權消息的轉發處理,并將處理的結果和設備授權響應數據,通過傳輸通道下發到對應的設備端。
示例代碼:
public static String samLicenseMessageProcess(String message) {
String productKey = null;
String payload = null;
DealDeviceRequestResponse response;
JSONObject inObj = JSON.parseObject(message);
if (inObj != null) {
productKey = inObj.getString("productKey");
payload = inObj.getString("payload");
}
DealDeviceRequestRequest request = new DealDeviceRequestRequest();
request.setProductKey(productKey);
request.setPayload(payload);
try {
response = client.getAcsResponse(request);
if (response.getSuccess() != true) {
System.out.println("deal device request, response = " + JSON.toJSONString(response));
return null;
}
} catch (ClientException e) {
e.printStackTrace();
System.out.println("deal device request, exception = " + e.getMessage());
return null;
}
JSONObject outObj = new JSONObject();
outObj.put("success", response.getSuccess());
outObj.put("data", response.getData());
return outObj.toJSONString();
}
上行的授權消息數據,定義成JSON格式,如下:
{
"productKey": "xxx",
"payload": "xxx"
}
下行的授權消息數據,可定義成JSON格式,如下:
{
"success": "true/false"
"data": "xxx"
}
3.2.5 設備端對接
3.2.5.1 SAM SDK框架:
IoT Application:
設備端需授權保護的應用模塊,調用授權SDK接口進行許可鑒權,通過LP Linkkit進行授權許可消息上報和下發。
IoT傳輸通道:
客戶物聯網平臺提供的數據連云的傳輸通道(上行和下行)。
IoT安全SDK:
SAM:IoT授權許可模塊。
ID2:IoT設備認證模塊,SDK v3.1.0及以上。
OSA:操作系統適配接口,廠商需根據使用的OS,重新進行接口適配。
HAL:硬件適配接口,提供算法庫和Soft-KM的適配接口,廠商需根據選擇的硬件平臺,重新進行接口適配。
3.2.5.2 SAM SDK獲取:
SAM SDK下載:
SAM Release Package目錄:
目錄/文件 | 說明 |
app | 測試用例,包括HAL和SAM |
example | 演示和試用代碼, 二級目錄說明如下: deps: IoT Linkkit v2.3代碼,只用作演示;項目如有需要,通過官網下載 HTTP - 提供基于HTTP協議的試用工程,包括demo app、License管理配置和消息轉發 mqtt - 提供基于mqtt的端側示例代碼 |
include | 頭文件 |
libs | 靜態庫 |
makefile | 編譯腳本 |
make.rules | 編譯系統配置文件,可配置編譯工具鏈和編譯參數 |
sample | 示例代碼, 本地環境的性能測試和試用 |
src | 需適配的OSA和HAL接口和參考實現 |
tools | 內容打包工具和配置模板 |
libs默認提供ID2-KM載體的靜態庫,其他載體如ID2-SE,可基于已適配和驗證的ID2靜態庫進行替換,方法如下:
獲取ID2-SE的靜態庫:libid2.a, libicrypt.a和libkm.a
打包生成最終的ID2靜態庫:
ar -x libid2.a
ar -x libicrypt.a
ar -x libkm.a
ar rc libid2.a *.o
ranlib libid2.a
rm -rf *.o
rm -rf libicrypt.a
rm -rf libkm.a
3.2.5.3 SAM SDK適配:
OSA接口適配:
實現src/osa/ls_osa.c中的接口:
已提供Linux系統的參考實現?。
?
HAL接口適配:
ID2-KM載體:
KM HAL接口適配:
實現deps/src/hal/km/demo/ls_hal_km.c中的接口:
已提供Linux系統的參考實現:
單獨預留的KM安全分區大于2K, 且需保證在系統升級和重啟時,分區數據不被破壞。
ls_hal_get_id接口,需使用設備硬件唯一標識。
SST HAL接口適配:
實現deps/src/hal/sst/demo/ls_hal_sst.c中的接口:
已提交Linux文件系統的參考實現:
需要配置到真實的存儲目錄,且需保證在系統升級和重啟時,分區數據不被破壞。
?
ID2-SE載體:
SST HAL接口適配:
實現deps/src/hal/sst/demo/ls_hal_sst.c中的接口:
已提供Linux文件系統的參考實現:
需要配置到真實的存儲目錄,且需保證在系統升級和重啟時,分區數據不被破壞。
?
SDK接口測試:
修改makefile.rules的編譯配置文件:
配置目標平臺(pLat := xxx)。
CROSS_COMPILE設置對應的編譯工具鏈。
CFLAGS設置編譯的配置參數。
執行編譯"make clean & make"。
HAL適配接口測試:
正確運行程序hal_app,可得到如下成功日志:
" ============================> HAL SST Test Pass.“
........
" ============================> HAL KM Test Pass.“ ->【只針對ID2-KM載體】
SAM接口單元測試:
正確運行程序sam_test,可得到如下成功日志:
" =================>SAM Client Unit Test Pass.“
?
3.2.5.4 SAM SDK集成:
授權初始化:
主要完成授權SDK的初始化、上行安全通道和上行消息事件的注冊,示例代碼如下:
#include "sam_api.h"
static sam_context context = {0};
static int on_publish(const char *topic,
const uint8_t *msg, uint32_t size, void *channel, const void *data)
{
/*
* TODO, Wrap and send SAM message through channel
*/
return 0;
}
static void on_message(void *channel)
{
/*
* TODO, Parse and Call sam_on_message to process message
*/
return;
}
int do_license_initialize(char *product_name, char *device_name, void *channel, char *topic)
{
sam_result result;
sam_config config;
config.sst_path = NULL;
config.dev_uuid = NULL;
config.timeout_ms = 10000;
result = sam_set_config(&config);
if (result != SAM_SUCCESS) {
printf("sam set config fail, 0x%x\n", result);
return -1;
}
result = sam_init_context(product_name, device_name, &context);
if (result != SAM_SUCCESS) {
printf("SAM init context fail, 0x%x\n", result);
return -1;
}
result = sam_set_pub_handle(&context, on_publish, channel);
if (result != SAM_SUCCESS) {
printf("SAM set pub_handle fail, 0x%x\n", result);
goto _out;
}
result = sam_set_pub_topic(&context, topic);
if (result != SAM_SUCCESS) {
printf("SAM set pub topic fail, 0x%x\n", result);
goto _out;
}
_out:
if (result != SAM_SUCCESS) {
sam_final_context(&context);
return -1;
} else {
return 0;
}
}
void do_license_finalize(sam_context *context)
{
sam_final_context(context);
}
product_name指產品標識(需是LP ProductKey),device_name設備唯一標識(可使用LP DeviceName,或其他設備硬件唯一標識),在同個產品product_name下唯一。
在調用授權初始化時,需先完成安全通道的創建,其中channel為安全通道的句柄。
授權初始化在應用/系統進程中,只需調用一次。
注冊的上行通道pub_handle,只需完成消息的上報。
根據安全通道協議的特性,完成授權下行消息的識別和處理(如MQTT消息訂閱)。
可在sam_config中進行授權全局配置:
設置請求超時時間(timeout_ms),超時時間有效值為1000ms - 20000ms, 當timeout_ms = 0時,使用默認的值10000ms。
許可存儲目錄sst_path:SAM靜態庫集成時,使用HAL接口中設置,此處配置不生效。
設備唯一標識dev_uuid:SAM靜態庫集成時,使用HAL接口中設置,此處配置不生效。
授權內容解密:
主要完成授權加密內容的解密,接口中會自動觸發授權的申請、存儲、加載和校驗等動作,示例代碼如下:
int license_content_decrypt(sam_context *context,
char *license_name, uint8_t *in, uint32_t in_len, uint8_t *out, uint32_t *out_len)
{
sam_result result;
sam_session session;
uint32_t lic_err = 0;
result = sam_open_session(context, &session, license_name);
if (result != SAM_SUCCESS) {
printf("SAM open session fail, 0x%x\n", result);
return -1;
}
result = sam_on_decryption(&session, in, in_len, out, out_len);
if (result != SAM_SUCCESS) {
printf("sam_on_decryption, 0x%x\n", result);
if (result == SAM_ERROR_LICENSE_ERROR) {
sam_get_lic_error_code(&session, &lic_err);
printf("license error code, %d\n", lic_err);
}
goto _out;;
}
result = SAM_SUCCESS;
_out:
sam_close_session(&session);
if (result != SAM_SUCCESS) {
return -1;
} else {
return 0;
}
}
sam_on_decryption接口中包含sam_chk_lic_rights(授權許可的申請、存儲和校驗等)。
license_name,即時License ID,使用內容加密生成的許可文件名(不包含后綴),如不相同,程序會報錯。
sam_on_decryption中調用sam_chk_lic_rights觸發授權連云申請和校驗,因此sam_on_decryption同樣可能阻塞當前線程,因此sam_on_decryption和下行消息的處理需在不同線程中。
?
注意事項:
SDK接口中product_name、device_name和license_name是字符串格式,有最大值限制(48、100、48)。
配置的SDK的安全存儲目錄需預先創建,里面會保存授權相關的密鑰和許可,此目錄在正常使用、設備重啟和系統升級時不會被擦除。
單機授權在授權申請,以及發現異常(如撤銷、過期、時間回滾等)會要求連網進行授權的云端校驗,如此時網絡不通/異常,接口sam_chk_lic_rights/sam_on_decryption會返回相應的錯誤,可在應用程序中顯示對應的提示信息:
SAM_ERROR_REVOKED - 設備已經被撤銷。
SAM_ERROR_LICENSE_ERROR - 設備授權錯誤,sam_get_lic_error_code獲得錯誤碼。
SAM_ERROR_TIMEOUT - 設備消息請求響應超時。
SAM_ERROR_CONMMUNICATION - 設備消息上報錯誤,需要連網。
?
參考實現:
離線環境 - 內容本地解密:
示例代碼:Release Package/sample/sam/sam_sample.c
可基于此,進行內容解密的性能測試。
聯網環境 - 授權許可下發:
示例代碼:Release Package/example
提供基于Spring Boot的SP Server Demo,管理后臺授權配置示例,以及授權消息的上下行交互邏輯。
3.2.6 調試驗證
軟件集成驗證:
模塊集成SAM SDK后,在每次內容解密時,接口內部自動調用許可鑒權接口進行校驗。
在內容第一次解密時,由于設備上不存在許可緩存,因此需聯網申請和下發許可。
當設備上成功下發和存儲授權許可,通過許可鑒權時,且內容解密成功,可通過日志查看許可信息:
License ID:許可唯一標識,SDK初始化時,由sam_open_session接口參數license_name傳入。
License interval:許可的離線間隔,超過離線間隔,設備需再次聯網更新許可。
License usage left_time:許可的有效剩余時間,單位為毫秒。
License usage count:許可的有效使用次數。
CRC32:保護內容的完整性校驗因子,解密后,通過CRC32校驗,說明內容解密正確。
3.2.7 查看使用記錄
請點擊AI算法保護-使用記錄,可查看IoT設備連接云端平臺獲取授權的使用記錄信息。
數據總覽界面。
已擁有授權:表示算法廠商為其授權的總配額信息。
已使用:表示設備廠商已經使用的授權數量。