• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 设备安全等级管理开发指导
2
3## 概述
4
5### 功能简介
6
7OpenHarmony的分布式技术可以实现不同设备的资源融合,将多个设备虚拟成一个“超级虚拟终端”。在这个“超级虚拟终端”的内部,处理、流转各类用户数据时,需要确保各个节点不因安全能力薄弱,成为整个“超级虚拟终端”的薄弱点,因此引入设备安全等级管理(DSLM)模块来解决这类问题。
8
9OpenHarmony设备安全等级管理(DSLM)模块,负责管理各种不同形态和种类的OpenHarmony设备的设备安全等级。在各类分布式业务中,当OpenHarmony对各类用户数据进行流转或处理的时候,可以调用本模块提供的接口获取相关目标设备的安全等级,并根据获取到的等级进行相应的处理。
10
11### 基本概念
12
13- 设备安全等级
14
15  OpenHarmony设备的安全等级取决于设备的系统安全能力。OpenHarmony系统安全能力,根植于硬件实现的三个可信根:启动、存储、计算。基于基础安全工程能力,重点围绕以下三点构建相关的安全技术和能力:设备完整性保护、数据机密性保护、漏洞攻防对抗。
16
17  OpenHarmony系统安全架构如下图所示:
18
19  ![OpenHarmony系统安全架构](figure/ohos_system_security_architecture.png)
20
21  上图为典型的OpenHarmony单设备系统安全架构,在不同种类OpenHarmony设备上的实现可以存在差异,取决于设备的威胁分析(风险高低)和设备的软硬件资源。OpenHarmony在参考业界权威的安全分级模型基础上,结合OpenHarmony实际的业务场景和设备分类,将OpenHarmony设备的安全能力划分为 5 个安全等级:SL1 ~ SL5。OpenHarmony操作系统生态体系中,要求高一级的设备安全能力默认包含低一级的设备安全能力。分级概要可参考下图:
22
23  ![OpenHarmony设备安全等级](figure/ohos_device_security_level.png)
24
25  - SL1为OpenHarmony设备中最低的安全等级。这类设备通常搭载轻量级系统和使用低端微处理器,业务形态较为单一,不涉及敏感数据的处理。本安全等级要求消除常见的错误,支持软件的完整性保护。若无法满足本等级的要求,则只能作为配件受OpenHarmony设备操控,无法反向操控OpenHarmony设备并进行更复杂的业务协同。
26
27  - SL2安全等级的OpenHarmony设备,可对自身数据进行标记并定义访问控制规则,实现自主的访问控制,需要具备基础的抗渗透能力。此级别设备可支持轻量化的可安全隔离环境,用于部署少量必需的安全业务。
28
29  - SL3安全等级的OpenHarmony设备,具备较为完善的安全保护能力。其操作系统具有较为完善的安全语义,可支持强制访问控制。系统可结构化为关键保护元素和非关键保护元素,其关键保护元素被明确定义的安全策略模型保护。此级别设备应具备一定的抗渗透能力,可对抗常见的漏洞利用方法。
30
31  - SL4安全等级的OpenHarmony设备,可信基应保持足够的精简,具备防篡改的能力。SL4的实现应足够精简和安全,可对关键保护元素的访问控制进行充分的鉴定和仲裁。此级别设备具备相当的抗渗透能力,可抑制绝大多数软件攻击。
32
33  - SL5安全等级的OpenHarmony设备,为OpenHarmony设备中具备最高等级安全防护能力的设备。系统核心软件模块应进行形式化验证。关键硬件模块如可信根、密码计算引擎等应具备防物理攻击能力,可应对实验室级别的攻击。此级别设备应具备高安全单元,如专用的安全芯片,用于强化设备的启动可信根、存储可信根、运行可信根。
34
35- DSLM
36
37  DSLM(Device Security Level Managerment), 是OpenHarmony设备安全等级管理的管理模块。负责各OpenHarmony设备之间的设备安全等级信息的同步和验证。并对外提供查询各设备的安全等级的接口。
38
39### 运作机制
40
41当“超级虚拟终端”内的各个设备有了自己的“设备安全等级”,这个“超级虚拟终端”的内部,各类用户数据的处理或流转便有了决策依据。例如:分布式文件存储服务,在处理某些敏感数据时,默认不允许相关数据存储在安全等级低于SL3的设备。
42
43### 约束与限制
44
45OpenHarmony设备的默认安全等级为SL1,设备制造商可以根据设备实际情况定制更高的安全等级。详细请参考章节[设备安全等级定制](#设备安全等级定制)。
46
47## 开发指导
48
49### 场景介绍
50
51各子系统在处理、流转各类用户数据时,可以调用DSLM模块提供的接口,获取相关设备的安全等级信息。并结合其所处理数据的实际情况,决策数据的进一步处理。
52
53### 接口说明
54
55所有接口均为native C内部接口,仅提供底层能力,不对App开放。相关接口列表如下:
56| 接口名                                                       | 说明                                         |
57| :----------------------------------------------------------- | :------------------------------------------- |
58| int32_t RequestDeviceSecurityInfo(const DeviceIdentify \*identify, const RequestOption \*option, DeviceSecurityInfo \*\*info); | 请求获取某设备的设备安全等级信息(同步接口) |
59| int32_t RequestDeviceSecurityInfoAsync(const DeviceIdentify \*identify, const RequestOption \*option, DeviceSecurityInfoCallback callback); | 请求获取某设备的设备安全等级信息(异步接口) |
60| void FreeDeviceSecurityInfo(DeviceSecurityInfo \*info);       | 释放设备安全等级信息                         |
61| int32_t GetDeviceSecurityLevelValue(const DeviceSecurityInfo \*info, int32_t \*level); | 从设备安全等级信息中提取对应的设备安全等级   |
62
63### 开发步骤
64
651. 编译依赖添加
66
67    ```undefined
68    external_deps += [ "device_security_level:dslm_sdk" ]
69    ```
70
712. 头文件依赖添加
72
73    ```cpp
74    #include "device_security_defines.h" // 关键数据结构定义头文件
75    #include "device_security_info.h" // 接口函数定义头文件
76    ```
77
783. 接口调用
79
80    ```cpp
81    // 查询参数1, 构造获取需要查询设备的设备UDID
82    const DeviceIdentify *device = GetDestDeviceUdid();
83
84    // 查询参数2,查询RequestOption构造
85    const RequestOption *option = DEFAULT_OPTION;
86
87    // 查询参数3,设备安全等级信息指针,用来接收返回结果
88    DeviceSecurityInfo *info = NULL;
89
90    // 调用RequestDeviceSecurityInfo接口获取对端设备的设备安全等级信息:
91    int32_t ret = RequestDeviceSecurityInfo(device, DEFAULT_OPTION, &info);
92
93    int32_t level = 0;
94    // 从设备安全等级信息中提取设备安全等级字段
95    ret = GetDeviceSecurityLevelValue(info, &level);
96    if (ret == SUCCESS) {
97        // 查询成功。
98        return;
99    }
100    // 结束处理前,需要释放内存
101    FreeDeviceSecurityInfo(info);
102    ```
103
104### 开发示例
105
106假设需要开发具备文件分享功能的某业务,为了防止部分敏感文件被无意识的分享出来。可以在其发送任意文件前增加如下判断处理:
107
108- 当目标设备的设备安全等级大于或者等于SL3时,默认允许该文件的传递。
109- 当目标设备的设备安全等级小于SL3时,默认拒绝该文件的外传,同时弹框告知用户。
110
1111. 同步接口使用示例
112
113```cpp
114void CheckDestDeviceSecurityLevel(const DeviceIdentify *device, RequestOption *option)
115{
116    // 设备安全等级信息指针
117    DeviceSecurityInfo *info = NULL;
118    // 调用同步接口获取设备的安全等级等级信息
119    int32_t ret = RequestDeviceSecurityInfo(device, option, &info);
120    if (ret != SUCCESS) {
121        // 获取信息失败。此场景建议开发者根据实际情况进行重试
122        return;
123    }
124    int32_t level = 0;
125    // 从设备安全等级信息中提取设备安全等级字段
126    ret = GetDeviceSecurityLevelValue(info, &level);
127    if (ret != SUCCESS) {
128        // 提取信息失败, 此场景建议开发者根据实际情况进行重试
129        return;
130    }
131    // 成功获取到设备安全等级,确认当前操作允许的最低安全等级
132    // 假设当前操作允许的最低设备安全等级为3
133    if (level >= 3) {
134        // 目标设备的设备安全等级满足要求, 相关业务正常处理
135    } else {
136        // 目标设备的设备安全等级不满足要求, 建议开发者结合实际业务场景进行相应处理,例如告警、弹窗提示用户等
137    }
138    // 结束处理前,需要释放内存
139    FreeDeviceSecurityInfo(info);
140}
141```
142
1431. 异步接口使用示例
144
145```cpp
146// 回调函数
147void DeviceSecurityInfoCallback(const DeviceIdentify *identify, struct DeviceSecurityInfo *info)
148{
149    int32_t level = 0;
150    // 从设备安全等级信息中提取设备安全等级字段
151    int32_t ret = GetDeviceSecurityLevelValue(info, &level);
152    if (ret != SUCCESS) {
153        // 获取信息失败。此场景建议开发者根据实际情况进行重试
154        return;
155    }
156    // 成功获取到设备安全等级,确认当前操作允许的最低安全等级
157    // 假设当前操作允许的最低设备安全等级为3
158    if (level >= 3) {
159        // 目标设备的设备安全等级满足要求, 相关业务正常处理
160    } else {
161        // 目标设备的设备安全等级不满足要求, 建议开发者结合实际业务场景进行相应处理,例如告警、弹窗提示用户等
162    }
163    // 结束处理前,需要释放内存
164    FreeDeviceSecurityInfo(info);
165}
166
167void CheckDestDeviceSecurityLevelAsync(const DeviceIdentify *device, RequestOption *option)
168{
169    // 调用异步接口获取设备设备的安全等级等级信息
170    int ret = RequestDeviceSecurityInfoAsync(device, option, DeviceSecurityInfoCallback);
171    if (ret != SUCCESS) {
172        // 获取信息失败,此场景建议开发者根据实际情况进行重试
173        // 此场景下callback不会回调。
174        return;
175    }
176    // 调用成功,等待callback回调。
177}
178```
179
180## 设备安全等级定制
181
182### 设备安全等级凭据
183
184为了保证设备安全等级信息的完整性和不可抵赖性。设备的安全等级信息需要封装在“设备安全等级凭据”(简称为“凭据”)文件中在设备间进行传递,凭据中除了包含设备的安全等级信息之外,还可以包含设备型号、设备版本号等其它设备固有属性,同时使用PKI技术对上述信息进行签名。并结合[设备认证](https://gitee.com/openharmony/security_deviceauth)、[HUKS](https://gitee.com/openharmony/security_huks)等OpenHarmony其他基础安全能力。最大程度的保证了凭据传递的安全性。
185
186### 默认实现
187
188OpenHarmony的设备安全等级管理模块提供了安全等级信息同步与验证的默认实现。它假定所有OpenHarmony设备的安全等级为SL1,并且采用了一套较为宽松的验证方案。详细细节可以参考[相关源码](https://gitee.com/openharmony/security_device_security_level/tree/master/oem_property/ohos)189
190设备制造商可以根据设备实际情况,参考[基本概念](#基本概念)章节的描述,修改默认的设备安全等级信息。与此同时,设备制造商还可以将OpenHarmony中的默认实现替换为更加严格的验证策略,包括但不限于采用更加精确的一机一凭据策略、从服务器定期下载更新的凭据并严格认证凭据的签发者和有效期、使用TEE(Trusted Execution Environment)甚至SE(Secure Element)对凭据文件进行进一步的签名等流程。
191
192### 凭据文件生成步骤
193
194凭据文件为4段BASE64编码的字符串,中间用"."链接,示例如下:
195
196```undefined
197<base64-header>.<base64-payload>.<base64-signature>.<base64-attestation>
198```
199
200#### 1. 构造header
201
202当前header为固定的json字符串,其格式化显示如下
203
204``` json
205{
206    "typ": "DSL"
207}
208```
209
210对原header字符串进行BASE64编码,得到`<base64-header>`:
211
212```undefined
213eyJ0eXAiOiAiRFNMIn0=
214```
215
216#### 2. 构造payload
217
218根据设备实际情况构造payload的json字符串,示例如下:
219
220``` json
221{
222    "type": "debug",
223    "manufacture": "ohos",
224    "brand": "rk3568",
225    "model": "rk3568",
226    "softwareVersion": "3.2.2",
227    "securityLevel": "SL1",
228    "signTime": "20220209150259",
229    "version": "1.0.1"
230}
231```
232
233对payload字符串进行BASE64编码,得到`<base64-payload>`:
234
235```undefined
236eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9
237```
238
239payload中各字段说明如下:
240
241|     字段名      |      字段说明      | 是否必选字段 |       取值范围        |
242| :-------------: | :----------------: | :----------: | :-------------------: |
243|      type       |    凭据发布类型    |      是      |    [debug release]    |
244|   manufacture   |   设备制造商信息   |      是      |    string [0..128]    |
245|      brand      |    设备品牌信息    |      是      |    string [0..128]    |
246|      model      |    设备型号信息    |      是      |    string [0..128]    |
247| softwareVersion | 设备软件版本号信息 |      是      |    string [0..128]    |
248|  securityLevel  |  设备安全等级信息  |      是      | [SL1 SL2 SL3 SL4 SL5] |
249|    signTime     |   本凭据签名时间   |      是      |    string [0..128]    |
250|     version     |    本凭据版本号    |      是      |    string [0..32]     |
251|       sn        |    设备SN序列号    |      否      |    string [0..128]    |
252|      udid       |   设备UDID序列号   |      否      |    string [0..128]    |
253
254#### 3. 构造signature
255
256signature是对前面header和payload的签名
257
258##### 3.1 构造构建待签名的原始数据
259
260将BASE64编码后的header和payload合并,中间用符号"."连接,得到`<base64-head>.<base64-payload>`
261示例如下:
262
263```undefined
264eyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9
265```
266
267##### 3.2 生成签名私钥
268
269凭据文件使用ECDSA签名算法对原始数据进行签名,首先生成签名用ECDSA密钥对:`<ecc-l3-pk>`和`<ecc-l3-sk>`
270
271> ![notice](../public_sys-resources/icon-notice.gif)**注意:**
272> 本流程需要在安全可靠的环境中执行,例如符合相关安全要求的服务器密码机中,以确保用于签名的密钥不被泄露
273
274##### 3.3 对原始数据进行签名
275
276将`<base64-head>.<base64-payload>`作为参数,使用刚刚生成的ECC私钥`<ecc-l3-sk>`对其进行签名,并对签名结果进行BASE64编码,得到签名结果值`<base64-signature>`:
277
278```undefined
279MGUCMDb9xoiFzTWVkHDU3VWSVQ59gLyw4TchZ0+eQ3vUfQsLt3Hkg0r7a/PmhkNr3X/mTgIxAIywIRE6vRTRs0xk6xKp8A0XwMMiIyjZlujPJfasCvFonpsvXLAqCAIYbe1J0k4Zfg==
280```
281
282#### 4. 构造attestation
283
284> ![notice](../public_sys-resources/icon-notice.gif)**注意:**
285> 本流程需要在安全可靠的环境中执行,例如符合相关安全要求的服务器密码机中,以确保用于签名的密钥不被泄露
286> 本流程涉及到的各密钥对不需要每次都重复生成,在确保密钥安全的前提下,后续可以直接复用。
287
288##### 4.1 生成三级签名验证信息
289
2901. 首先生成二级签名用ECDSA密钥对:`<ecc-l2-pk>`和`<ecc-l2-sk>`
2912. 使用`<ecc-l2-sk>` 对3.2章节生成的`<ecc-l3-pk>`进行签名,得到`<ecc-l3-pk-signature>`
2923. 将`<ecc-l3-pk>`和`<ecc-l3-pk-signature>`组合成json字符串示例如下:
293
294``` json
295{
296    "userPublicKey": "<ecc-l3-pk>",
297    "signature": "<ecc-l3-pk-signature>"
298}
299```
300
301##### 4.2 生成二级签名验证信息
302
3031. 生成一级签名用ECDSA密钥对:`<ecc-root-pk>`和`<ecc-root-sk>`
3042. 使用`<ecc-root-sk>` 对4.1章节生成的`<ecc-l2-pk>`进行签名,得到`<ecc-l2-pk-signature>`
3053. 将`<ecc-l3-pk>`和`<ecc-l3-pk-signature>`组合成json字符串示例如下:
306
307``` json
308{
309    "userPublicKey": "<ecc-l2-pk>",
310    "signature": "<ecc-l2-pk-signature>"
311}
312```
313
314##### 4.3 生成根签名验证信息
315
3161. 使用`<ecc-root-sk>` 对4.2章节生成的`<ecc-root-pk>`进行签名(即自签名),得到`<ecc-root-pk-self-signature>`
3172. 将`<ecc-root-pk>`和`<ecc-root-pk-self-signature>`组合成json字符串示例如下:
318
319``` json
320{
321    "userPublicKey": "<ecc-root-pk>",
322    "signature": "<ecc-root-pk-self-signature>"
323}
324```
325
326##### 4.4 合并生成attestation
327
3281. 将上述三组签名信息合并到一个json数组中:
329
330    ```json
331    [
332        {
333            "userPublicKey": "<ecc-l3-pk>",
334            "signature": "<ecc-l3-pk-signature>"
335        },
336        {
337            "userPublicKey": "<ecc-l2-pk>",
338            "signature": "<ecc-l2-pk-signature>"
339        },
340        {
341            "userPublicKey": "<ecc-root-pk>",
342            "signature": "<ecc-root-pk-self-signature>"
343        }
344    ]
345    ```
346
3472. 对该数据进行base64编码,得到`<base64-attestation>`
348
349    ```undefined
350    W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCREdOMU9xYWZrWFc2a0l1SEZrMVQ0TS84RVJUY3p0eWRDaGtramFROEkzNEc2Q3E1aTNJcnczVnRhQS9KTTF2a0lHOUZDVWRUaHZFUlJFUTFUdG9xemdxZW9SUzVwQW1EYUUyalEwYzdDem8rOHVUWTRIYW1weXZ1TENtenlYUXFnPT0iLCAic2lnbmF0dXJlIjogIk1HTUNMeHVjUnoyZndKZ092QkxyU1U3K1hlVTA3R0EyVXhZbDFMbEJLUnVIUS9wZlNWVHBEd0ZHSTNTb3h5ODR3NThIQWpBeGRtNEY3b3YvYUtEL0NFZi9QZlZDWHVlbE1mQys1L3pkUExXUUJEVnlGdWQrNVdYL3g4U083VXM5UGFhRW1mZz0ifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJHMWU3TDJVd1AyWWxTajB2RWViUGJpNVpLMDh5NS9UeHRWb3VrRFpIUGtSNlRtb2JoVGpyMVRVNzZpUkU4bDlWQlhuU1h1QVB6cjBuSHdKVkdVZVJMdmp4MVh0YUZReE9QNjhjNlIvRTdFWkZ2STdRUFg1N0tvRkhYdkEvVlJaNnc9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01FUVdFNnk0Rm42SFg1ekFvTzNkYzl5cG1Sd2lBclplc2o5aVBROTZEaEhuNXJkRTdNaGFMdWNRZ0MvaXhjSWJsZ0l3QkN5aFBvRUg2RjFITFlwM2xqbWVncVlZQ1E5NHEyZm1kbDB6dHhrWEVTOVpPOVRNSUZQRVpKYlpmUnU5ZHcyOSJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZRUUlDWmpWUTV4bkE0c2RMbUJzUmVaMzRJeWdkSmZhanA3SnRReFBzU2RwWTJXV0FneXp6Rm40OFFRRWhoU1BtdzhJYUU3VlJKRENBT3FYRnhGektJbFBFTDFvcFJDUmhhWmJrRzc5Y3ZrWC9HVVhlaFVYc2V2ZGhyb2VRVERFdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTUdQRndvSDJLbHhwbVZhWXRWV1ViMHpDSUJxYXFXY2F6czFqOVp4YklLUmVkR2tJY0VJdHN0UFoxdnVTanYvNDJnSXdSeGZPcTRoQTdNMHlGV2ZPSndqRTlTc2JsYXhvRDNiRTZCYzN2QjUyMmsyQ0ZJNWJqelpkeUFTVW04d2J2TW5WIn1d
351    ```
352
353#### 5. 构造完整的凭据
354
355用符号"."连接上述四段数据,最终得到 `<base64-header>.<base64-payload>.<base64-signature>.<base64-attestation>`,其示例如下:
356
357```undefined
358eyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9.MGUCMDb9xoiFzTWVkHDU3VWSVQ59gLyw4TchZ0+eQ3vUfQsLt3Hkg0r7a/PmhkNr3X/mTgIxAIywIRE6vRTRs0xk6xKp8A0XwMMiIyjZlujPJfasCvFonpsvXLAqCAIYbe1J0k4Zfg==.W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCREdOMU9xYWZrWFc2a0l1SEZrMVQ0TS84RVJUY3p0eWRDaGtramFROEkzNEc2Q3E1aTNJcnczVnRhQS9KTTF2a0lHOUZDVWRUaHZFUlJFUTFUdG9xemdxZW9SUzVwQW1EYUUyalEwYzdDem8rOHVUWTRIYW1weXZ1TENtenlYUXFnPT0iLCAic2lnbmF0dXJlIjogIk1HTUNMeHVjUnoyZndKZ092QkxyU1U3K1hlVTA3R0EyVXhZbDFMbEJLUnVIUS9wZlNWVHBEd0ZHSTNTb3h5ODR3NThIQWpBeGRtNEY3b3YvYUtEL0NFZi9QZlZDWHVlbE1mQys1L3pkUExXUUJEVnlGdWQrNVdYL3g4U083VXM5UGFhRW1mZz0ifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJHMWU3TDJVd1AyWWxTajB2RWViUGJpNVpLMDh5NS9UeHRWb3VrRFpIUGtSNlRtb2JoVGpyMVRVNzZpUkU4bDlWQlhuU1h1QVB6cjBuSHdKVkdVZVJMdmp4MVh0YUZReE9QNjhjNlIvRTdFWkZ2STdRUFg1N0tvRkhYdkEvVlJaNnc9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01FUVdFNnk0Rm42SFg1ekFvTzNkYzl5cG1Sd2lBclplc2o5aVBROTZEaEhuNXJkRTdNaGFMdWNRZ0MvaXhjSWJsZ0l3QkN5aFBvRUg2RjFITFlwM2xqbWVncVlZQ1E5NHEyZm1kbDB6dHhrWEVTOVpPOVRNSUZQRVpKYlpmUnU5ZHcyOSJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZRUUlDWmpWUTV4bkE0c2RMbUJzUmVaMzRJeWdkSmZhanA3SnRReFBzU2RwWTJXV0FneXp6Rm40OFFRRWhoU1BtdzhJYUU3VlJKRENBT3FYRnhGektJbFBFTDFvcFJDUmhhWmJrRzc5Y3ZrWC9HVVhlaFVYc2V2ZGhyb2VRVERFdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTUdQRndvSDJLbHhwbVZhWXRWV1ViMHpDSUJxYXFXY2F6czFqOVp4YklLUmVkR2tJY0VJdHN0UFoxdnVTanYvNDJnSXdSeGZPcTRoQTdNMHlGV2ZPSndqRTlTc2JsYXhvRDNiRTZCYzN2QjUyMmsyQ0ZJNWJqelpkeUFTVW04d2J2TW5WIn1d
359```
360
361### 凭据交换协议
362
363设备安全等级模块在感知到有新设备上线时,会通过[分布式软总线](https://gitee.com/openharmony/communication_dsoftbus)提供的通道向该设备请求其设备安全等级凭据。
364
365凭据请求报文格式如下:
366
367``` json
368{
369    "message": 1,
370    "payload": {
371        "version": 196608,
372        "challenge": "0102030405060708",
373        "support": [
374            300
375        ]
376    }
377}
378```
379
380其中各个字段解释如下:
381
382|  字段名   |               含义解释                |
383| :-------: | :-----------------------------------: |
384|  message  | 消息头,取值1表示设备安全等级凭据请求 |
385|  payload  |      消息payload,具体的请求信息      |
386|  version  |           请求端协议版本号            |
387| challenge |       本次请求信息对应的挑战值        |
388|  support  |       请求端支持的凭据格式列表        |
389
390对端设备在接受到凭据请求后,会按照如下格式进行回复
391
392``` json
393{
394    "message": 2,
395    "payload": {
396        "version": 196608,
397        "type": 300,
398        "challenge": "0102030405060708",
399        "info": "YWJjZAEDBQcJ..."
400    }
401}
402```
403
404其中各个字段解释如下:
405|  字段名   |                          含义解释                          |
406| :-------: | :--------------------------------------------------------: |
407|  message  |           消息头,取值2表示设备安全等级凭据应答            |
408|  payload  |                消息payload,具体的应答信息                 |
409|  version  |                      应答端协议版本号                      |
410|   type    |     应答端本次返回的凭据格式,用来描述如何解析info字段     |
411| challenge |                  本次应答信息对应的挑战值                  |
412|   info    | 签名后的凭据信息,同时还包含设备绑定关系、挑战值校验等信息 |
413
414### 工具使用介绍
415
416为方便开发者对于“凭据文件”的进一步理解,设备安全等级管理模块提供了[凭据工具](https://gitee.com/openharmony/security_device_security_level/blob/master/oem_property/ohos/dslm_cred_tool.py),该工具是一个python脚本,基于OPENSSL命令行的简单封装,可以便捷的提供凭据文件的签发和验证功能。
417其使用方法如下:
418
4191. 签名密钥初始化:
420
421    ``` undefined
422    ./dslm_cred_tool.py init
423    ```
424
4252. 凭据文件的生成:
426
427   生成一个名为cred.txt的凭据文件,并指定设备型号为rk3568、设备版本号为3.0.0、设备安全等级为SL3等payload信息。
428
429    ``` undefined
430    ./dslm_cred_tool.py create --field-manufacture OHOS --field-brand rk3568  --field-model rk3568 --field-software-version 3.0.0 --field-security-level SL3 --cred-file cred.txt
431    ```
432
433    上述命令可以生成一个凭据示例文件如下:
434
435    ``` undefined
436    cat cred.txt
437    eyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIk9IT1MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4wLjAiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDMiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTUzMDMiLCAidmVyc2lvbiI6ICIxLjAuMSJ9.MGQCMEqZy/snsRyjMupnEvTpQfhQn+IcdCc5Q3NGxllNQVhoZX8PNyw6ATTgyx+26ghmtQIwVH5KwQ4/VejxckeHmtkBVhofhgmRapzvyVnyiB3PdsU7nvHk8A/zC7PFy1CWBG3z.W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCQzFXRUxSVlU1NGp1U1ZXWlUrT29CM3hacFd5MWg3QW5uSFdKWm5QbTB3S2l0ZlJZelJKZ3FiUGQyZ3ltVXBUWVl1cmhyRDQxbFdPbUNzcmt0VWdaNTFXdGNCTmc5SG1GODkzc2ZHVFM5eUJNS0JoMGcxSHZaSVFSN1k0S3FXaWpnPT0iLCAic2lnbmF0dXJlIjogIk1HUUNNRFVicTZ2Z2R1YVF0bFVwOTR0azd4VjRJcEx2WVZWY3Y4aFNOTkw0azdPRHhmbEVGTHJFaUdPRWhwMUcweGFGYlFJd1pUbTk1cWx4OTBFZnptV3VIOGlEY2ZWYVlQS2N5SEYwR2ZFcEUzb1NESzQwZEFOZ0FJMWVQY09rTzBPOTdnTFAifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJGKzY1a0lSYTM2dkE4QVZWNXFrcUozYXpXTkdGQy9oaVdPL0tFNHR0S1pMOUsyNlhzQ2hQbjVNc3BlT2F3b1dqSU02bTVLOFZTcU1DYlZNN0svY0VRU0tYdDJTeVJGZERVZU9TaFZmQm9YVmxqaXRUU2puN0V5Q2pERVZiWjFRNEE9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01HanF2cnZ5VW1YNVZLVVc1UkFkUTNkZ2hBYmNBazBRQnppQlFWMVFZUTNQMVFPSzdMckM1b0RObXh6T2Y0QUtmd0l3SzVWU2x3ZG5JSUR6Zm9PUXBEUVAycGhTVGgxSGVjbXJRK1F4VGxWelo0aHJsdnJyd2xCNnp0T3pWRFdNblRELyJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZCa2FDNE9mc2VTREt2cW8vbU5VaUtXQ3JtK1VDNGFQcjVsODRNM2tMVCtDdkd3OWhqOGJ6d2I1MzNtVVlFZVhWWWtUdFlRYWRURkRJZXV1dGIzNU1QZDlEKytNMFRFWnZvcTY4NFhoYTVQMzBUbVRhK0ZvOG02UWliZWc3TmFQdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTURJcmpNYzhvODVPRHFZT0R4c05PcmpYdUhvWjM5endpZlhVTkdDc0lkN2xjU2FWcnhCVlNqRjRyaWg5Y1R6T3dRSXdWQXA3RUF5c1pucEI5REJWVWczQzlMeGQ3eTQxWEMwYVVPcGZUKzI3REVvWmM1WVVldDFGa1FwdmFQckduaFhVIn1d
438    ```
439
4403. 凭据文件的校验:
441
442    ``` undefined
443    ./dslm_cred_tool.py verify --cred-file cred.txt
444    ```
445
446    验证回显如下:
447
448    ``` undefined
449    head:
450    {
451      "typ": "DSL"
452    }
453    payload:
454    {
455      "type": "debug",
456      "manufacture": "OHOS",
457      "brand": "rk3568",
458      "model": "rk3568",
459      "softwareVersion": "3.0.0",
460      "securityLevel": "SL3",
461      "signTime": "20220209155303",
462      "version": "1.0.1"
463    }
464    verify success!
465    ```
466
467## 常见问题
468
469- Q:凭据工具如何在真实的生产环境中使用?
470
471    A:凭据工具不可以直接用于生产环境,它仅仅是一个示例,用来演示凭据的具体格式和生成过程。在真实的生产环境中,我们建议参考凭据工具的实现,在符合相关安全要求的服务器密码机中进行凭据的生成和相关密钥的保存。
472
473- Q:真实的生产环境中,如何对凭据文件进行校验?
474
475    A:我们建议设备制造商使用妥善保管的私钥对凭据文件进行签名,同时替换OpenHarmony中对于凭据文件的默认校验流程,增加对凭据签名者的严格校验。例如仅认可信任机构签发的凭据文件、增加凭据和设备ID的一对一强绑定等校验。
476
477## 参考资料
478
479480