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