1e41f4b71Sopenharmony_ci# Development on Device Security Level Management
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### DSLM
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThe OpenHarmony distributed technology can converge resources from different devices to form a Super Device. Poor security capabilities of any device may threaten the security of the Super Device.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciThe Device Security Level Management (DSLM) module is introduced to manage the security levels of OpenHarmony devices. When different types of user data are hopped or processed in OpenHarmony distributed services, the DSLM APIs can be called to obtain the security levels of related devices for subsequent processing.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci### Basic Concepts
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci- Device security level
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci  The security level of an OpenHarmony device depends on the system security capabilities of the device. The OpenHarmony system security capabilities are based on the root of trust (RoT) for boot, RoT for storage, and RoT for compute on the hardware. Security technologies and capabilities focus on device integrity protection, data confidentiality protection, and vulnerability defense.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci  The following figure shows the OpenHarmony security architecture.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci  ![OpenHarmony system security architecture](figures/ohos_system_security_architecture.png)
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci  The above figure shows the typical security architecture for a single device. The architecture may vary depending on the risk level as well as the software and hardware resources of the device. The security capabilities of OpenHarmony devices are classified into five levels from SL1 to SL5, based on the industry standard security classification model and actual OpenHarmony service scenarios and device types. In the OpenHarmony ecosystem, higher security levels include all the capabilities of lower security levels by default. The figure below shows the security levels of OpenHarmony devices.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci  ![OpenHarmony device security levels](figures/ohos_device_security_level.png)
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci  - SL1: SL1 is the lowest security level of OpenHarmony devices. Usually equipped with a lightweight operating system and low-end microprocessors, such devices implement simple services and do not need to process sensitive data. SL1 devices are required to support software integrity protection and eliminate common errors. Devices that cannot meet the requirements of SL1 can only be controlled by OpenHarmony devices. They cannot control OpenHarmony devices for more complex service collaboration.
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci  - SL2: OpenHarmony devices of SL2 can label their own data and define access control rules to implement discretionary access control (DAC). These devices must have basic anti-penetration capabilities. Devices of this level support a lightweight, secure, and isolated environment for deploying a small number of necessary security services.
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci  - SL3: OpenHarmony devices of SL3 have comprehensive security protection capabilities, and their operating systems have relatively complete security semantics and support mandatory access control (MAC). The system data can be structured as critical elements and non-critical elements. The critical elements are protected by a well-defined security policy model. Devices of this level must have certain anti-penetration capabilities to defend against common vulnerability exploits.
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci  - SL4: OpenHarmony devices of SL4 must have simplified trusted computing base (TCB) and come with anti-tampering capabilities. The implementation of SL4 should be concise and secure enough. Adequate authentication and arbitration are required for any access to critical elements. Devices of this level have considerable anti-penetration capabilities and can defend against most software attacks.
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci  - SL5: SL5 indicates the highest security protection capabilities for OpenHarmony devices. The system core software modules must have passed formal verification. Key hardware modules, such as the RoT and cryptographic computing engine, must be able to defend against physical attacks and attacks simulated in labs. Devices at this level must have high-security units, such as dedicated security chips, to enhance the boot, storage, and running of the root of trust (RoT).
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci- DSLM
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci  DSLM is a module to manage the security levels of OpenHarmony devices. It verifies and updates device security level information for OpenHarmony devices in collaboration. It also provides an interface for querying the security level of each device.
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci### Working Principles
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ciThe security level of each device in a Super Device provides the decision-making criteria for processing or hopping various user data. For example, the distributed file storage service does not allow sensitive data to be stored on devices with security level lower than SL3.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci### Constraints
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ciThe default security level of OpenHarmony devices is SL1. Device manufacturers can customize a higher security level based on service requirements. For details, see [Customizing Device Security Levels](#customizing-device-security-levels).
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ciIf data processing or hopping fails because the device security level is low during debugging of distributed services, you can temporarily increase the security level of related devices. For details, see [Tool](#tool).
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci## Development Guidelines
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci### When to Use
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ciWhen processing or hopping various user data, a subsystem can invoke the APIs provided by the DSLM module to obtain the security level information of related devices. Then, the subsystems determine the subsequent processing based on the security level and data to be processed.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci### Available APIs
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ciAll the APIs are native C interfaces for implementing underlying capabilities and are not open to apps. The APIs are described as follows:
58e41f4b71Sopenharmony_ci| API                                                      | Description                                        |
59e41f4b71Sopenharmony_ci| :----------------------------------------------------------- | :------------------------------------------- |
60e41f4b71Sopenharmony_ci| int32_t RequestDeviceSecurityInfo(const DeviceIdentify \*identify, const RequestOption \*option, DeviceSecurityInfo \*\*info); | Requests the security level information of a device synchronously.|
61e41f4b71Sopenharmony_ci| int32_t RequestDeviceSecurityInfoAsync(const DeviceIdentify \*identify, const RequestOption \*option, DeviceSecurityInfoCallback callback); | Requests the security level information of a device asynchronously.|
62e41f4b71Sopenharmony_ci| void FreeDeviceSecurityInfo(DeviceSecurityInfo \*info);       | Releases the device security level information.|
63e41f4b71Sopenharmony_ci| int32\_t GetDeviceSecurityLevelValue(const DeviceSecurityInfo \*info, int32_t \*level); | Obtains the device security level from the security level information.|
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci### How to Develop
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci1. Add the dependencies for compilation.
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci    ```undefined
70e41f4b71Sopenharmony_ci    external_deps += [ "device_security_level:dslm_sdk" ]
71e41f4b71Sopenharmony_ci    ```
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci2. Add the header files of dependencies.
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci    ```cpp
76e41f4b71Sopenharmony_ci    #include "device_security_defines.h" // Header file for defining critical data structures.
77e41f4b71Sopenharmony_ci    #include "device_security_info.h" // Header file for defining APIs.
78e41f4b71Sopenharmony_ci    ```
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci3. Call APIs.
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci    ```cpp
83e41f4b71Sopenharmony_ci    // Obtain the unique device identifier (UDID) of the device of which the security level is to be queried.
84e41f4b71Sopenharmony_ci    const DeviceIdentify *device = GetDestDeviceUdid();
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci    // Obtain the RequestOption.
87e41f4b71Sopenharmony_ci    const RequestOption *option = DEFAULT_OPTION;
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci    // Define a pointer to the device security level obtained.
90e41f4b71Sopenharmony_ci    DeviceSecurityInfo *info = NULL;
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci    // Call RequestDeviceSecurityInfo to obtain the device security level information of the peer device.
93e41f4b71Sopenharmony_ci    int32_t ret = RequestDeviceSecurityInfo(device, DEFAULT_OPTION, &info);
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci    int32_t level = 0;
96e41f4b71Sopenharmony_ci    // Obtain the device security level from the device security level information.
97e41f4b71Sopenharmony_ci    ret = GetDeviceSecurityLevelValue(info, &level);
98e41f4b71Sopenharmony_ci    if (ret == SUCCESS) {
99e41f4b71Sopenharmony_ci        // The device security level is obtained.
100e41f4b71Sopenharmony_ci        FreeDeviceSecurityInfo(info);
101e41f4b71Sopenharmony_ci        return;
102e41f4b71Sopenharmony_ci    }
103e41f4b71Sopenharmony_ci    // Release the memory before the processing is complete.
104e41f4b71Sopenharmony_ci    FreeDeviceSecurityInfo(info);
105e41f4b71Sopenharmony_ci    ```
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci### Development Example
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ciA service with the file sharing function needs to be developed. To prevent sensitive files from being shared unintentionally, the following judgments must be performed before any file is sent:
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci- If the security level of the destination device is SL3 or higher, the service sends the file.
112e41f4b71Sopenharmony_ci- If the security level of the destination device is lower than SL3, the service denies the file transfer and display a dialog box to notify the user.
113e41f4b71Sopenharmony_ci
114e41f4b71Sopenharmony_ci**Example of synchronously obtaining the device security level**
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci```cpp
117e41f4b71Sopenharmony_civoid CheckDestDeviceSecurityLevel(const DeviceIdentify *device, RequestOption *option)
118e41f4b71Sopenharmony_ci{
119e41f4b71Sopenharmony_ci    // Pointer to the device security level information.
120e41f4b71Sopenharmony_ci    DeviceSecurityInfo *info = NULL;
121e41f4b71Sopenharmony_ci    // Obtain the security level information of the device.
122e41f4b71Sopenharmony_ci    int32_t ret = RequestDeviceSecurityInfo(device, option, &info);
123e41f4b71Sopenharmony_ci    if (ret != SUCCESS) {
124e41f4b71Sopenharmony_ci        // Failed to obtain the information. You can develop a retry process as required.
125e41f4b71Sopenharmony_ci        return;
126e41f4b71Sopenharmony_ci    }
127e41f4b71Sopenharmony_ci    int32_t level = 0;
128e41f4b71Sopenharmony_ci    // Obtain the device security level from the device security level information.
129e41f4b71Sopenharmony_ci    ret = GetDeviceSecurityLevelValue(info, &level);
130e41f4b71Sopenharmony_ci    if (ret != SUCCESS) {
131e41f4b71Sopenharmony_ci        // Failed to obtain the security level. You can develop a retry process as required.
132e41f4b71Sopenharmony_ci        FreeDeviceSecurityInfo(info);
133e41f4b71Sopenharmony_ci        return;
134e41f4b71Sopenharmony_ci    }
135e41f4b71Sopenharmony_ci    // After the device security level is successfully obtained, check the lowest security level required for the current operation.
136e41f4b71Sopenharmony_ci    // The lowest device security level required for the current operation is 3.
137e41f4b71Sopenharmony_ci    if (level >= 3) {
138e41f4b71Sopenharmony_ci        // The security level of the target device meets the requirements. Services are processed properly. 
139e41f4b71Sopenharmony_ci    } else {
140e41f4b71Sopenharmony_ci        // The security level of the target device does not meet the requirements. An alert or dialog box is displayed as required.
141e41f4b71Sopenharmony_ci    }
142e41f4b71Sopenharmony_ci    // Release the memory before the processing is complete.
143e41f4b71Sopenharmony_ci    FreeDeviceSecurityInfo(info);
144e41f4b71Sopenharmony_ci}
145e41f4b71Sopenharmony_ci```
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci**Example of asynchronously obtaining the device security level**
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci```cpp
150e41f4b71Sopenharmony_ci// Callback
151e41f4b71Sopenharmony_civoid DeviceSecurityInfoCallback(const DeviceIdentify *identify, struct DeviceSecurityInfo *info)
152e41f4b71Sopenharmony_ci{
153e41f4b71Sopenharmony_ci    int32_t level = 0;
154e41f4b71Sopenharmony_ci    // Obtain the device security level from the device security level information.
155e41f4b71Sopenharmony_ci    int32_t ret = GetDeviceSecurityLevelValue(info, &level);
156e41f4b71Sopenharmony_ci    if (ret != SUCCESS) {
157e41f4b71Sopenharmony_ci        // Failed to obtain the information. You can develop a retry process as required.
158e41f4b71Sopenharmony_ci        FreeDeviceSecurityInfo(info);
159e41f4b71Sopenharmony_ci        return;
160e41f4b71Sopenharmony_ci    }
161e41f4b71Sopenharmony_ci    // After the device security level is successfully obtained, check the lowest security level required for the current operation.
162e41f4b71Sopenharmony_ci    // The lowest device security level required for the current operation is 3.
163e41f4b71Sopenharmony_ci    if (level >= 3) {
164e41f4b71Sopenharmony_ci        // The security level of the target device meets the requirements. Services are processed properly. 
165e41f4b71Sopenharmony_ci    } else {
166e41f4b71Sopenharmony_ci        // The security level of the target device does not meet the requirements. An alert or dialog box is displayed as required.
167e41f4b71Sopenharmony_ci    }
168e41f4b71Sopenharmony_ci    // Release the memory before the processing is complete.
169e41f4b71Sopenharmony_ci    FreeDeviceSecurityInfo(info);
170e41f4b71Sopenharmony_ci}
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_civoid CheckDestDeviceSecurityLevelAsync(const DeviceIdentify *device, RequestOption *option)
173e41f4b71Sopenharmony_ci{
174e41f4b71Sopenharmony_ci    // Invoke the asynchronous callback to return the device security level obtained.
175e41f4b71Sopenharmony_ci    int ret = RequestDeviceSecurityInfoAsync(device, option, DeviceSecurityInfoCallback);
176e41f4b71Sopenharmony_ci    if (ret != SUCCESS) {
177e41f4b71Sopenharmony_ci        // Failed to obtain the security level. You can develop a retry process as required.
178e41f4b71Sopenharmony_ci        // In this case, the callback will not be invoked.
179e41f4b71Sopenharmony_ci        return;
180e41f4b71Sopenharmony_ci    }
181e41f4b71Sopenharmony_ci    // The callback is invoked. Wait for the callback to return the device security level.
182e41f4b71Sopenharmony_ci}
183e41f4b71Sopenharmony_ci```
184e41f4b71Sopenharmony_ci
185e41f4b71Sopenharmony_ci## Customizing Device Security Levels
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci### Device Security Level Credential
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ciTo ensure its integrity and non-repudiation, the security level information must be encapsulated in a "device security level credential" (credential for short) file for transmission between devices. In addition to the security level information of the device, the credential may include device attributes, such as the device model and version. Moreover, the credential must be signed using the public key infrastructure (PKI) technology. Other basic security capabilities of OpenHarmony, such as [Device Authentication](https://gitee.com/openharmony/security_device_auth) and [HUKS](https://gitee.com/openharmony/security_huks), are used to ensure secure transmission of credentials.
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ci### Default Implementation
192e41f4b71Sopenharmony_ci
193e41f4b71Sopenharmony_ciThe DSLM module provides default implementation of security level information synchronization and verification. It is assumed that the security level of all OpenHarmony devices is SL1, and a loose verification scheme is used. For details, see the [source code](https://gitee.com/openharmony/security_device_security_level/tree/master/oem_property/ohos).
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ciYou can change the device security level as required. For details about the OpenHarmony device security levels, see [Basic Concepts](#basic-concepts). You can also use more severe verification schemes, including but are not limited to using device-specific credential, periodically downloading updated credentials from a server and strictly authenticating the issuer and validity period of the credentials, and using Trusted Execution Environment (TEE) or even Secure Element (SE) to sign credential files.
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci### Generating a Credential File
198e41f4b71Sopenharmony_ci
199e41f4b71Sopenharmony_ciThe credential file consists of four Base64-encoded strings, separated by periods (.). The following is an example:
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci```undefined
202e41f4b71Sopenharmony_ci<base64-header>.<base64-payload>.<base64-signature>.<base64-attestation>
203e41f4b71Sopenharmony_ci```
204e41f4b71Sopenharmony_ci
205e41f4b71Sopenharmony_ci#### 1. Construct the `header`.
206e41f4b71Sopenharmony_ci
207e41f4b71Sopenharmony_ciThe header is a fixed JSON string in the following format:
208e41f4b71Sopenharmony_ci
209e41f4b71Sopenharmony_ci``` json
210e41f4b71Sopenharmony_ci{
211e41f4b71Sopenharmony_ci    "typ": "DSL"
212e41f4b71Sopenharmony_ci}
213e41f4b71Sopenharmony_ci```
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_ciEncode the header string to Base64 format to obtain `<base64-header>`.
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ci```undefined
218e41f4b71Sopenharmony_cieyJ0eXAiOiAiRFNMIn0=
219e41f4b71Sopenharmony_ci```
220e41f4b71Sopenharmony_ci
221e41f4b71Sopenharmony_ci#### 2. Construct the `payload`.
222e41f4b71Sopenharmony_ci
223e41f4b71Sopenharmony_ciConstruct the payload in a JSON string. The following is an example:
224e41f4b71Sopenharmony_ci
225e41f4b71Sopenharmony_ci``` json
226e41f4b71Sopenharmony_ci{
227e41f4b71Sopenharmony_ci    "type": "debug",
228e41f4b71Sopenharmony_ci    "manufacture": "ohos",
229e41f4b71Sopenharmony_ci    "brand": "rk3568",
230e41f4b71Sopenharmony_ci    "model": "rk3568",
231e41f4b71Sopenharmony_ci    "softwareVersion": "3.2.2",
232e41f4b71Sopenharmony_ci    "securityLevel": "SL1",
233e41f4b71Sopenharmony_ci    "signTime": "20220209150259",
234e41f4b71Sopenharmony_ci    "version": "1.0.1"
235e41f4b71Sopenharmony_ci}
236e41f4b71Sopenharmony_ci```
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ciEncode the payload string to Base64 format to obtain `<base64-payload>`.
239e41f4b71Sopenharmony_ci
240e41f4b71Sopenharmony_ci```undefined
241e41f4b71Sopenharmony_cieyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9
242e41f4b71Sopenharmony_ci```
243e41f4b71Sopenharmony_ci
244e41f4b71Sopenharmony_ciThe fields in the `payload` are described as follows:
245e41f4b71Sopenharmony_ci
246e41f4b71Sopenharmony_ci|     Field     |      Description     | Mandatory|       Value Range       |
247e41f4b71Sopenharmony_ci| :-------------: | :----------------: | :----------: | :-------------------: |
248e41f4b71Sopenharmony_ci|      type       |    Credential type.   |      Yes     |    [debug release]    |
249e41f4b71Sopenharmony_ci|   manufacture   |   Device manufacturer information.  |      Yes     |    string [0..128]    |
250e41f4b71Sopenharmony_ci|      brand      |    Device brand.   |      Yes     |    string [0..128]    |
251e41f4b71Sopenharmony_ci|      model      |    Device model.   |      Yes     |    string [0..128]    |
252e41f4b71Sopenharmony_ci| softwareVersion | Device software version.|      Yes     |    string [0..128]    |
253e41f4b71Sopenharmony_ci|  securityLevel  |  Device security level. |      Yes     | [SL1 SL2 SL3 SL4 SL5] |
254e41f4b71Sopenharmony_ci|    signTime     |   Time when the credential was signed.  |      Yes     |    string [0..128]    |
255e41f4b71Sopenharmony_ci|     version     |    Credential version.   |      Yes     |    string [0..32]     |
256e41f4b71Sopenharmony_ci|       sn        |    Device SN.   |      No     |    string [0..128]    |
257e41f4b71Sopenharmony_ci|      udid       |   Device UDID.  |      No     |    string [0..128]    |
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci#### 3. Construct the `signature`.
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ciConstruct the signature of the header and payload.
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci##### 3.1 Construct the raw data to be signed.
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ciCombine the Base64-encoded header and payload with a period (.) in between to obtain `<base64-head>.<base64-payload>`.
266e41f4b71Sopenharmony_ciExample:
267e41f4b71Sopenharmony_ci
268e41f4b71Sopenharmony_ci```undefined
269e41f4b71Sopenharmony_cieyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9
270e41f4b71Sopenharmony_ci```
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci##### 3.2 Generate a private key for signing data.
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ciThe Elliptic Curve Digital Signature algorithm (ECDSA) is used to sign the raw data in the credential file. Generate an ECDSA key pair `<ecc-l3-pk>` and `<ecc-l3-sk>` first.
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ci> ![notice](../public_sys-resources/icon-notice.gif)**NOTICE**
277e41f4b71Sopenharmony_ci>
278e41f4b71Sopenharmony_ci> This step must be performed in a secure and reliable environment, for example, a cryptographic machine that meets related security requirements, to ensure that the key generated is not disclosed.
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ci##### 3.3 Sign the raw data.
281e41f4b71Sopenharmony_ci
282e41f4b71Sopenharmony_ciUse the ECC private key `<ecc-l3-sk>` to sign `<base64-head>.<base64-payload>`, and encode the signature to Base64 format to obtain `<base64-signature>`.
283e41f4b71Sopenharmony_ci
284e41f4b71Sopenharmony_ci```undefined
285e41f4b71Sopenharmony_ciMGUCMDb9xoiFzTWVkHDU3VWSVQ59gLyw4TchZ0+eQ3vUfQsLt3Hkg0r7a/PmhkNr3X/mTgIxAIywIRE6vRTRs0xk6xKp8A0XwMMiIyjZlujPJfasCvFonpsvXLAqCAIYbe1J0k4Zfg==
286e41f4b71Sopenharmony_ci```
287e41f4b71Sopenharmony_ci
288e41f4b71Sopenharmony_ci#### 4. Construct the `attestation`.
289e41f4b71Sopenharmony_ci
290e41f4b71Sopenharmony_ci> ![notice](../public_sys-resources/icon-notice.gif)**NOTICE**
291e41f4b71Sopenharmony_ci>
292e41f4b71Sopenharmony_ci> This step must be performed in a secure and reliable environment, for example, a cryptographic machine that meets related security requirements, to ensure that the key used for signature is not disclosed.
293e41f4b71Sopenharmony_ci> The key pairs involved in this step do not need to be generated each time. Secure key pairs can be reused.
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ci##### 4.1 Generate verification information for an end-entity certificate signature.
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci1. Generate an ECDSA key pair `<ecc-l2-pk>` and `<ecc-l2-sk>` for an intermediate CA certificate signature.
298e41f4b71Sopenharmony_ci2. Use `<ecc-l2-sk>` to sign `<ecc-l3-pk>` (generated in step 3.2) to obtain `<ecc-l3-pk-signature>`.
299e41f4b71Sopenharmony_ci3. Combine `<ecc-l3-pk>` and `<ecc-l3-pk-signature>` into a JSON string. The following is an example:
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci``` json
302e41f4b71Sopenharmony_ci{
303e41f4b71Sopenharmony_ci    "userPublicKey": "<ecc-l3-pk>",
304e41f4b71Sopenharmony_ci    "signature": "<ecc-l3-pk-signature>"
305e41f4b71Sopenharmony_ci}
306e41f4b71Sopenharmony_ci```
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci##### 4.2 Generate verification information for an intermediate CA certificate signature.
309e41f4b71Sopenharmony_ci
310e41f4b71Sopenharmony_ci1. Generate an ECDSA key pair `<ecc-root-pk>` and `<ecc-root-sk>` for a root certificate signature.
311e41f4b71Sopenharmony_ci2. Use `<ecc-root-sk>` to sign `<ecc-l2-pk>` (generated in step 4.1) to obtain `<ecc-l2-pk-signature>`.
312e41f4b71Sopenharmony_ci3. Combine `<ecc-l3-pk>` and `<ecc-l3-pk-signature>` into a JSON string. 
313e41f4b71Sopenharmony_ciThe following is an example:
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci``` json
316e41f4b71Sopenharmony_ci{
317e41f4b71Sopenharmony_ci    "userPublicKey": "<ecc-l2-pk>",
318e41f4b71Sopenharmony_ci    "signature": "<ecc-l2-pk-signature>"
319e41f4b71Sopenharmony_ci}
320e41f4b71Sopenharmony_ci```
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ci##### 4.3 Generate root signature verification information.
323e41f4b71Sopenharmony_ci
324e41f4b71Sopenharmony_ci1. Use `<ecc-root-sk>` to sign the `<ecc-root-pk>` (generated in step 4.2) to obtain `<ecc-root-pk-self-signature>` (a self-signature).
325e41f4b71Sopenharmony_ci2. Combine `<ecc-root-pk>` and `<ecc-root-pk-self-signature>` into a JSON string. The following is an example: 
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci``` json
328e41f4b71Sopenharmony_ci{
329e41f4b71Sopenharmony_ci    "userPublicKey": "<ecc-root-pk>",
330e41f4b71Sopenharmony_ci    "signature": "<ecc-root-pk-self-signature>"
331e41f4b71Sopenharmony_ci}
332e41f4b71Sopenharmony_ci```
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ci##### 4.4 Generate the `attestation`.
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ci1. Combine the preceding three pieces of signature information into a JSON array.
337e41f4b71Sopenharmony_ci
338e41f4b71Sopenharmony_ci    ```json
339e41f4b71Sopenharmony_ci    [
340e41f4b71Sopenharmony_ci        {
341e41f4b71Sopenharmony_ci            "userPublicKey": "<ecc-l3-pk>",
342e41f4b71Sopenharmony_ci            "signature": "<ecc-l3-pk-signature>"
343e41f4b71Sopenharmony_ci        },
344e41f4b71Sopenharmony_ci        {
345e41f4b71Sopenharmony_ci            "userPublicKey": "<ecc-l2-pk>",
346e41f4b71Sopenharmony_ci            "signature": "<ecc-l2-pk-signature>"
347e41f4b71Sopenharmony_ci        },
348e41f4b71Sopenharmony_ci        {
349e41f4b71Sopenharmony_ci            "userPublicKey": "<ecc-root-pk>",
350e41f4b71Sopenharmony_ci            "signature": "<ecc-root-pk-self-signature>"
351e41f4b71Sopenharmony_ci        }
352e41f4b71Sopenharmony_ci    ]
353e41f4b71Sopenharmony_ci    ```
354e41f4b71Sopenharmony_ci
355e41f4b71Sopenharmony_ci2. Encode the JSON array to Base64 format to obtain `<base64-attestation>`.
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci    ```undefined
358e41f4b71Sopenharmony_ci    W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCREdOMU9xYWZrWFc2a0l1SEZrMVQ0TS84RVJUY3p0eWRDaGtramFROEkzNEc2Q3E1aTNJcnczVnRhQS9KTTF2a0lHOUZDVWRUaHZFUlJFUTFUdG9xemdxZW9SUzVwQW1EYUUyalEwYzdDem8rOHVUWTRIYW1weXZ1TENtenlYUXFnPT0iLCAic2lnbmF0dXJlIjogIk1HTUNMeHVjUnoyZndKZ092QkxyU1U3K1hlVTA3R0EyVXhZbDFMbEJLUnVIUS9wZlNWVHBEd0ZHSTNTb3h5ODR3NThIQWpBeGRtNEY3b3YvYUtEL0NFZi9QZlZDWHVlbE1mQys1L3pkUExXUUJEVnlGdWQrNVdYL3g4U083VXM5UGFhRW1mZz0ifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJHMWU3TDJVd1AyWWxTajB2RWViUGJpNVpLMDh5NS9UeHRWb3VrRFpIUGtSNlRtb2JoVGpyMVRVNzZpUkU4bDlWQlhuU1h1QVB6cjBuSHdKVkdVZVJMdmp4MVh0YUZReE9QNjhjNlIvRTdFWkZ2STdRUFg1N0tvRkhYdkEvVlJaNnc9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01FUVdFNnk0Rm42SFg1ekFvTzNkYzl5cG1Sd2lBclplc2o5aVBROTZEaEhuNXJkRTdNaGFMdWNRZ0MvaXhjSWJsZ0l3QkN5aFBvRUg2RjFITFlwM2xqbWVncVlZQ1E5NHEyZm1kbDB6dHhrWEVTOVpPOVRNSUZQRVpKYlpmUnU5ZHcyOSJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZRUUlDWmpWUTV4bkE0c2RMbUJzUmVaMzRJeWdkSmZhanA3SnRReFBzU2RwWTJXV0FneXp6Rm40OFFRRWhoU1BtdzhJYUU3VlJKRENBT3FYRnhGektJbFBFTDFvcFJDUmhhWmJrRzc5Y3ZrWC9HVVhlaFVYc2V2ZGhyb2VRVERFdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTUdQRndvSDJLbHhwbVZhWXRWV1ViMHpDSUJxYXFXY2F6czFqOVp4YklLUmVkR2tJY0VJdHN0UFoxdnVTanYvNDJnSXdSeGZPcTRoQTdNMHlGV2ZPSndqRTlTc2JsYXhvRDNiRTZCYzN2QjUyMmsyQ0ZJNWJqelpkeUFTVW04d2J2TW5WIn1d
359e41f4b71Sopenharmony_ci    ```
360e41f4b71Sopenharmony_ci
361e41f4b71Sopenharmony_ci#### 5. Construct a complete credential.
362e41f4b71Sopenharmony_ci
363e41f4b71Sopenharmony_ciPut the four pieces of data together with a period (.) in between to obtain `<base64-header>.<base64-payload>.<base64-signature>.<base64-attestation>`. The following is an example:
364e41f4b71Sopenharmony_ci
365e41f4b71Sopenharmony_ci```undefined
366e41f4b71Sopenharmony_cieyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIm9ob3MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4yLjIiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDEiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTAyNTkiLCAidmVyc2lvbiI6ICIxLjAuMSJ9.MGUCMDb9xoiFzTWVkHDU3VWSVQ59gLyw4TchZ0+eQ3vUfQsLt3Hkg0r7a/PmhkNr3X/mTgIxAIywIRE6vRTRs0xk6xKp8A0XwMMiIyjZlujPJfasCvFonpsvXLAqCAIYbe1J0k4Zfg==.W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCREdOMU9xYWZrWFc2a0l1SEZrMVQ0TS84RVJUY3p0eWRDaGtramFROEkzNEc2Q3E1aTNJcnczVnRhQS9KTTF2a0lHOUZDVWRUaHZFUlJFUTFUdG9xemdxZW9SUzVwQW1EYUUyalEwYzdDem8rOHVUWTRIYW1weXZ1TENtenlYUXFnPT0iLCAic2lnbmF0dXJlIjogIk1HTUNMeHVjUnoyZndKZ092QkxyU1U3K1hlVTA3R0EyVXhZbDFMbEJLUnVIUS9wZlNWVHBEd0ZHSTNTb3h5ODR3NThIQWpBeGRtNEY3b3YvYUtEL0NFZi9QZlZDWHVlbE1mQys1L3pkUExXUUJEVnlGdWQrNVdYL3g4U083VXM5UGFhRW1mZz0ifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJHMWU3TDJVd1AyWWxTajB2RWViUGJpNVpLMDh5NS9UeHRWb3VrRFpIUGtSNlRtb2JoVGpyMVRVNzZpUkU4bDlWQlhuU1h1QVB6cjBuSHdKVkdVZVJMdmp4MVh0YUZReE9QNjhjNlIvRTdFWkZ2STdRUFg1N0tvRkhYdkEvVlJaNnc9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01FUVdFNnk0Rm42SFg1ekFvTzNkYzl5cG1Sd2lBclplc2o5aVBROTZEaEhuNXJkRTdNaGFMdWNRZ0MvaXhjSWJsZ0l3QkN5aFBvRUg2RjFITFlwM2xqbWVncVlZQ1E5NHEyZm1kbDB6dHhrWEVTOVpPOVRNSUZQRVpKYlpmUnU5ZHcyOSJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZRUUlDWmpWUTV4bkE0c2RMbUJzUmVaMzRJeWdkSmZhanA3SnRReFBzU2RwWTJXV0FneXp6Rm40OFFRRWhoU1BtdzhJYUU3VlJKRENBT3FYRnhGektJbFBFTDFvcFJDUmhhWmJrRzc5Y3ZrWC9HVVhlaFVYc2V2ZGhyb2VRVERFdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTUdQRndvSDJLbHhwbVZhWXRWV1ViMHpDSUJxYXFXY2F6czFqOVp4YklLUmVkR2tJY0VJdHN0UFoxdnVTanYvNDJnSXdSeGZPcTRoQTdNMHlGV2ZPSndqRTlTc2JsYXhvRDNiRTZCYzN2QjUyMmsyQ0ZJNWJqelpkeUFTVW04d2J2TW5WIn1d
367e41f4b71Sopenharmony_ci```
368e41f4b71Sopenharmony_ci
369e41f4b71Sopenharmony_ci### Credential Exchange Protocol
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ciWhen detecting a device goes online, the DSLM module requests the device security level credential from the device through the channel provided by [DSoftBus](https://gitee.com/openharmony/communication_dsoftbus).
372e41f4b71Sopenharmony_ci
373e41f4b71Sopenharmony_ciThe packet for requesting the credential is in the following format:
374e41f4b71Sopenharmony_ci
375e41f4b71Sopenharmony_ci``` json
376e41f4b71Sopenharmony_ci{
377e41f4b71Sopenharmony_ci    "message": 1,
378e41f4b71Sopenharmony_ci    "payload": {
379e41f4b71Sopenharmony_ci        "version": 196608,
380e41f4b71Sopenharmony_ci        "challenge": "0102030405060708",
381e41f4b71Sopenharmony_ci        "support": [
382e41f4b71Sopenharmony_ci            300
383e41f4b71Sopenharmony_ci        ]
384e41f4b71Sopenharmony_ci    }
385e41f4b71Sopenharmony_ci}
386e41f4b71Sopenharmony_ci```
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ciThe fields in the request message are described as follows:
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ci|  Field  |               Description               |
391e41f4b71Sopenharmony_ci| :-------: | :-----------------------------------: |
392e41f4b71Sopenharmony_ci|  message  | Message header. The value **1** indicates a request for the device security level credential.|
393e41f4b71Sopenharmony_ci|  payload  |      Message payload, which is the specific request information.|
394e41f4b71Sopenharmony_ci|  version  |           Version of the protocol used by the requester.|
395e41f4b71Sopenharmony_ci| challenge |       Challenge value corresponding to this request.|
396e41f4b71Sopenharmony_ci|  support  |       List of credential formats supported by the requester.|
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ciAfter receiving the request, the peer device returns a response in the following format:
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci``` json
401e41f4b71Sopenharmony_ci{
402e41f4b71Sopenharmony_ci    "message": 2,
403e41f4b71Sopenharmony_ci    "payload": {
404e41f4b71Sopenharmony_ci        "version": 196608,
405e41f4b71Sopenharmony_ci        "type": 300,
406e41f4b71Sopenharmony_ci        "challenge": "0102030405060708",
407e41f4b71Sopenharmony_ci        "info": "YWJjZAEDBQcJ..."
408e41f4b71Sopenharmony_ci    }
409e41f4b71Sopenharmony_ci}
410e41f4b71Sopenharmony_ci```
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ciThe fields in the response message are described as follows:
413e41f4b71Sopenharmony_ci|  Field  |                          Description                         |
414e41f4b71Sopenharmony_ci| :-------: | :--------------------------------------------------------: |
415e41f4b71Sopenharmony_ci|  message  |           Message header. The value **2** indicates a response to the request for the device security level credential.|
416e41f4b71Sopenharmony_ci|  payload  |                Message payload, which is the specific response information.|
417e41f4b71Sopenharmony_ci|  version  |                      Version of the protocol used by the responder. |
418e41f4b71Sopenharmony_ci|   type    |     Format of the credential returned, which describes how to parse the **info** field.|
419e41f4b71Sopenharmony_ci| challenge |                  Challenge value corresponding to this response message.|
420e41f4b71Sopenharmony_ci|   info    | Signed credential information, which also includes the device information and challenge value verification information.|
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ci### Tool
423e41f4b71Sopenharmony_ci
424e41f4b71Sopenharmony_ciThe DSLM module provides a [credential tool](https://gitee.com/openharmony/security_device_security_level/blob/master/oem_property/ohos/standard/dslm_cred_tool.py) to help you better understand the issuing and verification of credentials. This tool is a Python script encapsulated with OpenSSL commands.
425e41f4b71Sopenharmony_ciYou can use the tool as follows:
426e41f4b71Sopenharmony_ci
427e41f4b71Sopenharmony_ci1. Initialize the signature key.
428e41f4b71Sopenharmony_ci
429e41f4b71Sopenharmony_ci    ``` undefined
430e41f4b71Sopenharmony_ci    ./dslm_cred_tool.py init
431e41f4b71Sopenharmony_ci    ```
432e41f4b71Sopenharmony_ci
433e41f4b71Sopenharmony_ci2. Generate a credential.
434e41f4b71Sopenharmony_ci
435e41f4b71Sopenharmony_ci    For example, to generate a credential file **cred.txt** with the device model of **rk3568**, device version of **3.0.0**, and device security level of **SL3**, run the following command:
436e41f4b71Sopenharmony_ci
437e41f4b71Sopenharmony_ci    ``` undefined
438e41f4b71Sopenharmony_ci    ./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
439e41f4b71Sopenharmony_ci    ```
440e41f4b71Sopenharmony_ci
441e41f4b71Sopenharmony_ci    A credential file is generated as follows:
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci    ``` undefined
444e41f4b71Sopenharmony_ci    cat cred.txt
445e41f4b71Sopenharmony_ci    eyJ0eXAiOiAiRFNMIn0=.eyJ0eXBlIjogImRlYnVnIiwgIm1hbnVmYWN0dXJlIjogIk9IT1MiLCAiYnJhbmQiOiAicmszNTY4IiwgIm1vZGVsIjogInJrMzU2OCIsICJzb2Z0d2FyZVZlcnNpb24iOiAiMy4wLjAiLCAic2VjdXJpdHlMZXZlbCI6ICJTTDMiLCAic2lnblRpbWUiOiAiMjAyMjAyMDkxNTUzMDMiLCAidmVyc2lvbiI6ICIxLjAuMSJ9.MGQCMEqZy/snsRyjMupnEvTpQfhQn+IcdCc5Q3NGxllNQVhoZX8PNyw6ATTgyx+26ghmtQIwVH5KwQ4/VejxckeHmtkBVhofhgmRapzvyVnyiB3PdsU7nvHk8A/zC7PFy1CWBG3z.W3sidXNlclB1YmxpY0tleSI6ICJNSG93RkFZSEtvWkl6ajBDQVFZSkt5UURBd0lJQVFFTEEySUFCQzFXRUxSVlU1NGp1U1ZXWlUrT29CM3hacFd5MWg3QW5uSFdKWm5QbTB3S2l0ZlJZelJKZ3FiUGQyZ3ltVXBUWVl1cmhyRDQxbFdPbUNzcmt0VWdaNTFXdGNCTmc5SG1GODkzc2ZHVFM5eUJNS0JoMGcxSHZaSVFSN1k0S3FXaWpnPT0iLCAic2lnbmF0dXJlIjogIk1HUUNNRFVicTZ2Z2R1YVF0bFVwOTR0azd4VjRJcEx2WVZWY3Y4aFNOTkw0azdPRHhmbEVGTHJFaUdPRWhwMUcweGFGYlFJd1pUbTk1cWx4OTBFZnptV3VIOGlEY2ZWYVlQS2N5SEYwR2ZFcEUzb1NESzQwZEFOZ0FJMWVQY09rTzBPOTdnTFAifSwgeyJ1c2VyUHVibGljS2V5IjogIk1Ib3dGQVlIS29aSXpqMENBUVlKS3lRREF3SUlBUUVMQTJJQUJGKzY1a0lSYTM2dkE4QVZWNXFrcUozYXpXTkdGQy9oaVdPL0tFNHR0S1pMOUsyNlhzQ2hQbjVNc3BlT2F3b1dqSU02bTVLOFZTcU1DYlZNN0svY0VRU0tYdDJTeVJGZERVZU9TaFZmQm9YVmxqaXRUU2puN0V5Q2pERVZiWjFRNEE9PSIsICJzaWduYXR1cmUiOiAiTUdRQ01HanF2cnZ5VW1YNVZLVVc1UkFkUTNkZ2hBYmNBazBRQnppQlFWMVFZUTNQMVFPSzdMckM1b0RObXh6T2Y0QUtmd0l3SzVWU2x3ZG5JSUR6Zm9PUXBEUVAycGhTVGgxSGVjbXJRK1F4VGxWelo0aHJsdnJyd2xCNnp0T3pWRFdNblRELyJ9LCB7InVzZXJQdWJsaWNLZXkiOiAiTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkZCa2FDNE9mc2VTREt2cW8vbU5VaUtXQ3JtK1VDNGFQcjVsODRNM2tMVCtDdkd3OWhqOGJ6d2I1MzNtVVlFZVhWWWtUdFlRYWRURkRJZXV1dGIzNU1QZDlEKytNMFRFWnZvcTY4NFhoYTVQMzBUbVRhK0ZvOG02UWliZWc3TmFQdz09IiwgInNpZ25hdHVyZSI6ICJNR1FDTURJcmpNYzhvODVPRHFZT0R4c05PcmpYdUhvWjM5endpZlhVTkdDc0lkN2xjU2FWcnhCVlNqRjRyaWg5Y1R6T3dRSXdWQXA3RUF5c1pucEI5REJWVWczQzlMeGQ3eTQxWEMwYVVPcGZUKzI3REVvWmM1WVVldDFGa1FwdmFQckduaFhVIn1d
446e41f4b71Sopenharmony_ci    ```
447e41f4b71Sopenharmony_ci
448e41f4b71Sopenharmony_ci3. Verify a credential.
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci    ``` undefined
451e41f4b71Sopenharmony_ci    ./dslm_cred_tool.py verify --cred-file cred.txt
452e41f4b71Sopenharmony_ci    ```
453e41f4b71Sopenharmony_ci
454e41f4b71Sopenharmony_ci    The command output is as follows:
455e41f4b71Sopenharmony_ci
456e41f4b71Sopenharmony_ci    ``` undefined
457e41f4b71Sopenharmony_ci    head:
458e41f4b71Sopenharmony_ci    {
459e41f4b71Sopenharmony_ci      "typ": "DSL"
460e41f4b71Sopenharmony_ci    }
461e41f4b71Sopenharmony_ci    payload:
462e41f4b71Sopenharmony_ci    {
463e41f4b71Sopenharmony_ci      "type": "debug",
464e41f4b71Sopenharmony_ci      "manufacture": "OHOS",
465e41f4b71Sopenharmony_ci      "brand": "rk3568",
466e41f4b71Sopenharmony_ci      "model": "rk3568",
467e41f4b71Sopenharmony_ci      "softwareVersion": "3.0.0",
468e41f4b71Sopenharmony_ci      "securityLevel": "SL3",
469e41f4b71Sopenharmony_ci      "signTime": "20220209155303",
470e41f4b71Sopenharmony_ci      "version": "1.0.1"
471e41f4b71Sopenharmony_ci    }
472e41f4b71Sopenharmony_ci    verify success!
473e41f4b71Sopenharmony_ci    ```
474e41f4b71Sopenharmony_ci
475e41f4b71Sopenharmony_ci4. Send the generated credential file to the target device and make it take effect.
476e41f4b71Sopenharmony_ci   
477e41f4b71Sopenharmony_ci   Temporarily disable write protection.
478e41f4b71Sopenharmony_ci   ``` undefined
479e41f4b71Sopenharmony_ci   hdc_std target mount
480e41f4b71Sopenharmony_ci   hdc_std shell "setenforce 0"
481e41f4b71Sopenharmony_ci   ```
482e41f4b71Sopenharmony_ci
483e41f4b71Sopenharmony_ci   Send the generated credential file to the device.
484e41f4b71Sopenharmony_ci   ``` undefined
485e41f4b71Sopenharmony_ci   hdc_std file send cred.txt  /system/etc/dslm_finger.cfg
486e41f4b71Sopenharmony_ci   ```
487e41f4b71Sopenharmony_ci
488e41f4b71Sopenharmony_ci   Restart the device to make the new credential file take effect.
489e41f4b71Sopenharmony_ci   ``` undefined
490e41f4b71Sopenharmony_ci   hdc_std reboot
491e41f4b71Sopenharmony_ci   ```
492e41f4b71Sopenharmony_ci
493e41f4b71Sopenharmony_ci## FAQs
494e41f4b71Sopenharmony_ci
495e41f4b71Sopenharmony_ci- Q: How can I use the credential tool in a production environment?
496e41f4b71Sopenharmony_ci
497e41f4b71Sopenharmony_ci    A: The credential tool cannot be directly used in the production environment. It is used to demonstrate the format and generation process of credentials. In the production environment, you are advised to generate credentials and save related keys in a cryptographic machine that meets related security requirements.
498e41f4b71Sopenharmony_ci
499e41f4b71Sopenharmony_ci- Q: How do I verify a credential in a production environment?
500e41f4b71Sopenharmony_ci
501e41f4b71Sopenharmony_ci    A: You are advised to use a properly kept private key to sign the credential and use more severe signature verification process instead of the default verification process provided by the DSLM module. For example, allow only the credentials issued by trusted certification authorities (CAs), and bind the credential and device ID to enhance the security.
502e41f4b71Sopenharmony_ci
503e41f4b71Sopenharmony_ci- Q: The default security level of OpenHarmony devices is SL1. How do I do if the distributed service (distributed file system) fails to process sensitive data due to insufficient permission? 
504e41f4b71Sopenharmony_ci
505e41f4b71Sopenharmony_ci    A: You can solve the problem by temporarily increasing the security level of the related devices. For details, see [Tool](#tool).
506