1e41f4b71Sopenharmony_ci# MD Operation (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciThe message digest (MD) algorithm allows a fixed-length digest to be generated from data of arbitrary size by using the hash algorithm. The MD algorithm is also referred to as a hash algorithm or a one-way hash algorithm.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciWhen the same digest algorithm is used, the generated digest (hash value) has the following features:
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci- The same message always results in the same hash value.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci- The digest generated is of the fixed length no matter the length of messages. (The digest length is determined by the algorithm used).
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci- It is almost impossible to find two different messages with the same hash value. (The probability still exists, depending on the length of the digest.)
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci## Supported Algorithms and Specifications
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciThe **Supported Type** column in the following table lists the algorithm to be used when a **Md** instance is created.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci| MD Algorithm| Supported Type| API Version| 
22e41f4b71Sopenharmony_ci| -------- | -------- | -------- |
23e41f4b71Sopenharmony_ci| HASH | SHA1 | 9+ | 
24e41f4b71Sopenharmony_ci| HASH | SHA224 | 9+ | 
25e41f4b71Sopenharmony_ci| HASH | SHA256 | 9+ | 
26e41f4b71Sopenharmony_ci| HASH | SHA384 | 9+ | 
27e41f4b71Sopenharmony_ci| HASH | SHA512 | 9+ | 
28e41f4b71Sopenharmony_ci| HASH | MD5 | 9+ | 
29e41f4b71Sopenharmony_ci| HASH | SM3 | 10+ | 
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci## Adding the Dynamic Library in the CMake Script
33e41f4b71Sopenharmony_ci```txt
34e41f4b71Sopenharmony_ci   target_link_libraries(entry PUBLIC libohcrypto.so)
35e41f4b71Sopenharmony_ci```
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci## How to Develop
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciDuring the MD operation, you can use **OH_CryptoDigest_Update()** to pass in all the data at a time or pass in data by segment. For the same piece of data, the result will be the same no matter how the data is passed. Use the appropriate method based on the data size.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciThe following provides examples of MD operations with different data passing methods.
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci### MD (Passing In Full Data)
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci1. Use [OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create) with the MD algorithm **SHA256** to generate an MD operation instance ([OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest)).
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci2. Use [OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update) to pass in the data for generating an MD. The amount of data to be passed in by a single **OH_CryptoDigest_Update()** operation is not limited.
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci3. Use [OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final) to generate an MD.
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci4. Use [OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength) to obtain the MD length, in bytes.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci5. Use [OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy) to destroy the [OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest) instance.
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci**Example**
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci```c++
60e41f4b71Sopenharmony_ci#include "CryptoArchitectureKit/crypto_common.h"
61e41f4b71Sopenharmony_ci#include "CryptoArchitectureKit/crypto_digest.h"
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_cistatic OH_Crypto_ErrCode doTestMd()
64e41f4b71Sopenharmony_ci{
65e41f4b71Sopenharmony_ci    OH_Crypto_ErrCode ret;
66e41f4b71Sopenharmony_ci    OH_CryptoDigest *ctx = nullptr;
67e41f4b71Sopenharmony_ci    uint8_t testData[] = "0123456789";
68e41f4b71Sopenharmony_ci    Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData), .len = sizeof(testData)};
69e41f4b71Sopenharmony_ci    Crypto_DataBlob out = {.data = nullptr, .len = 0};
70e41f4b71Sopenharmony_ci    int mdLen = 0;
71e41f4b71Sopenharmony_ci    ret = OH_CryptoDigest_Create("SHA256", &ctx);
72e41f4b71Sopenharmony_ci    if (ret != CRYPTO_SUCCESS) {
73e41f4b71Sopenharmony_ci        return ret;
74e41f4b71Sopenharmony_ci    }
75e41f4b71Sopenharmony_ci    do {
76e41f4b71Sopenharmony_ci        ret = OH_CryptoDigest_Update(ctx, &in);
77e41f4b71Sopenharmony_ci        if (ret != CRYPTO_SUCCESS) {
78e41f4b71Sopenharmony_ci            break;
79e41f4b71Sopenharmony_ci        }
80e41f4b71Sopenharmony_ci        ret = OH_CryptoDigest_Final(ctx, &out);
81e41f4b71Sopenharmony_ci        if (ret != CRYPTO_SUCCESS) {
82e41f4b71Sopenharmony_ci            break;
83e41f4b71Sopenharmony_ci        }
84e41f4b71Sopenharmony_ci        mdLen = OH_CryptoDigest_GetLength(ctx);
85e41f4b71Sopenharmony_ci    } while (0);
86e41f4b71Sopenharmony_ci    OH_Crypto_FreeDataBlob(&out);
87e41f4b71Sopenharmony_ci    OH_DigestCrypto_Destroy(ctx);
88e41f4b71Sopenharmony_ci    return ret;
89e41f4b71Sopenharmony_ci}
90e41f4b71Sopenharmony_ci```
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci### MD (Passing In Data by Segment)
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci1. Use [OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_create) with the MD algorithm **SHA256** to generate an MD operation instance ([OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest)).
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci2. Call [OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_update) multiple times to pass in 20 bytes each time.
97e41f4b71Sopenharmony_ci
98e41f4b71Sopenharmony_ci3. Use [OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_final) to generate an MD.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci4. Use [OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest_getlength) to obtain the MD length, in bytes.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci5. Use [OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_digestcrypto_destroy) to destroy the [OH_CryptoDigest](../../reference/apis-crypto-architecture-kit/_crypto_digest_api.md#oh_cryptodigest) instance.
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci**Example**
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci```c++
107e41f4b71Sopenharmony_ci#include <stdlib.h>
108e41f4b71Sopenharmony_ci#include "CryptoArchitectureKit/crypto_common.h"
109e41f4b71Sopenharmony_ci#include "CryptoArchitectureKit/crypto_digest.h"
110e41f4b71Sopenharmony_ci#define OH_CRYPTO_DIGEST_DATA_MAX (1024 * 1024 * 100)
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_cistatic OH_Crypto_ErrCode doLoopMd()
113e41f4b71Sopenharmony_ci{
114e41f4b71Sopenharmony_ci    OH_Crypto_ErrCode ret;
115e41f4b71Sopenharmony_ci    OH_CryptoDigest *ctx = nullptr;
116e41f4b71Sopenharmony_ci    uint8_t *testData = (uint8_t *)malloc(OH_CRYPTO_DIGEST_DATA_MAX);
117e41f4b71Sopenharmony_ci    Crypto_DataBlob out = {.data = nullptr, .len = 0};
118e41f4b71Sopenharmony_ci    int mdLen = 0;
119e41f4b71Sopenharmony_ci    int isBlockSize = 20;
120e41f4b71Sopenharmony_ci    int offset = 0;
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci    ret = OH_CryptoDigest_Create("SHA256", &ctx);
123e41f4b71Sopenharmony_ci    if (ret != CRYPTO_SUCCESS) {
124e41f4b71Sopenharmony_ci        return ret;
125e41f4b71Sopenharmony_ci    }
126e41f4b71Sopenharmony_ci    do {
127e41f4b71Sopenharmony_ci        for (int i = 0; i < 640 / isBlockSize; i++) {
128e41f4b71Sopenharmony_ci            Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData + offset),
129e41f4b71Sopenharmony_ci                                .len = static_cast<size_t>(isBlockSize)};
130e41f4b71Sopenharmony_ci            ret = OH_CryptoDigest_Update(ctx, &in);
131e41f4b71Sopenharmony_ci            if (ret != CRYPTO_SUCCESS) {
132e41f4b71Sopenharmony_ci                break;
133e41f4b71Sopenharmony_ci            }
134e41f4b71Sopenharmony_ci            offset += isBlockSize;
135e41f4b71Sopenharmony_ci        }
136e41f4b71Sopenharmony_ci        ret = OH_CryptoDigest_Final(ctx, &out);
137e41f4b71Sopenharmony_ci        if (ret != CRYPTO_SUCCESS) {
138e41f4b71Sopenharmony_ci            break;
139e41f4b71Sopenharmony_ci        }
140e41f4b71Sopenharmony_ci        mdLen = OH_CryptoDigest_GetLength(ctx);
141e41f4b71Sopenharmony_ci    } while (0);
142e41f4b71Sopenharmony_ci    OH_Crypto_FreeDataBlob(&out);
143e41f4b71Sopenharmony_ci    OH_DigestCrypto_Destroy(ctx);
144e41f4b71Sopenharmony_ci    return ret;
145e41f4b71Sopenharmony_ci}
146e41f4b71Sopenharmony_ci```
147