• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 消息摘要计算SHA256(C/C++)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10对应的算法规格请查看[消息摘要计算算法规格](crypto-generate-message-digest-overview.md#支持的算法与规格)。
11
12## 在CMake脚本中链接相关动态库
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16
17## 开发步骤
18
19在调用update接口传入数据时,可以[一次性传入所有数据](#摘要算法一次性传入),也可以把数据人工分段,然后[分段update](#分段摘要算法)。对于同一段数据而言,计算结果没有差异。对于数据量较大的数据,开发者可以根据实际需求选择是否分段传入。
20
21下面分别提供两种方式的示例代码。
22
23### 摘要算法(一次性传入)
24
251. 调用[OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_create),指定摘要算法SHA256,生成摘要实例(OH_CryptoDigest)。
26
272. 调用[OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_update),传入自定义消息,进行摘要更新计算。单次update长度没有限制。
28
293. 调用[OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_final),获取摘要计算结果。
30
314. 调用[OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_getlength),获取摘要计算长度,单位为字节。
32
335. 调用[OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_digestcrypto_destroy),销毁摘要实例(OH_CryptoDigest)。
34
35- 以下使用单次传入数据,获取摘要计算结果为例:
36
37```c++
38#include "CryptoArchitectureKit/crypto_common.h"
39#include "CryptoArchitectureKit/crypto_digest.h"
40#include <string.h>
41
42static OH_Crypto_ErrCode doTestMd()
43{
44    OH_Crypto_ErrCode ret;
45    OH_CryptoDigest *ctx = nullptr;
46    char *testData = const_cast<char *>("0123456789");
47    Crypto_DataBlob in = {.data = (uint8_t *)(testData), .len = strlen(testData)};
48    Crypto_DataBlob out = {.data = nullptr, .len = 0};
49    int mdLen = 0;
50    ret = OH_CryptoDigest_Create("SHA256", &ctx);
51    if (ret != CRYPTO_SUCCESS) {
52        return ret;
53    }
54    do {
55        ret = OH_CryptoDigest_Update(ctx, &in);
56        if (ret != CRYPTO_SUCCESS) {
57            break;
58        }
59        ret = OH_CryptoDigest_Final(ctx, &out);
60        if (ret != CRYPTO_SUCCESS) {
61            break;
62        }
63        mdLen = OH_CryptoDigest_GetLength(ctx);
64    } while (0);
65    OH_Crypto_FreeDataBlob(&out);
66    OH_DigestCrypto_Destroy(ctx);
67    return ret;
68}
69```
70
71### 分段摘要算法
72
731. 调用[OH_CryptoDigest_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_create),指定摘要算法SHA256,生成摘要实例(OH_CryptoDigest)。
74
752. 传入自定义消息,将一次传入数据量设置为20字节,多次调用[OH_CryptoDigest_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_update),进行摘要更新计算。
76
773. 调用[OH_CryptoDigest_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_final),获取摘要计算结果。
78
794. 调用[OH_CryptoDigest_GetLength](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_cryptodigest_getlength),获取摘要计算长度,单位为字节。
80
815. 调用[OH_DigestCrypto_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-digest-h.md#oh_digestcrypto_destroy),销毁摘要实例(OH_CryptoDigest)。
82
83- 以下使用分段传入数据,获取摘要计算结果为例:
84
85```c++
86#include <stdlib.h>
87#include "CryptoArchitectureKit/crypto_common.h"
88#include "CryptoArchitectureKit/crypto_digest.h"
89#define OH_CRYPTO_DIGEST_DATA_MAX (1024 * 1024 * 100)
90
91static OH_Crypto_ErrCode doLoopMd()
92{
93    OH_Crypto_ErrCode ret;
94    OH_CryptoDigest *ctx = nullptr;
95    uint8_t *testData = (uint8_t *)malloc(OH_CRYPTO_DIGEST_DATA_MAX);
96    if (testData == nullptr) {
97        return CRYPTO_MEMORY_ERROR;
98    }
99    Crypto_DataBlob out = {.data = nullptr, .len = 0};
100    int mdLen = 0;
101    int isBlockSize = 20;
102    int offset = 0;
103
104    ret = OH_CryptoDigest_Create("SHA256", &ctx);
105    if (ret != CRYPTO_SUCCESS) {
106        return ret;
107    }
108    do {
109        for (int i = 0; i < 640 / isBlockSize; i++) {
110            Crypto_DataBlob in = {.data = reinterpret_cast<uint8_t *>(testData + offset),
111                                .len = static_cast<size_t>(isBlockSize)};
112            ret = OH_CryptoDigest_Update(ctx, &in);
113            if (ret != CRYPTO_SUCCESS) {
114                break;
115            }
116            offset += isBlockSize;
117        }
118        ret = OH_CryptoDigest_Final(ctx, &out);
119        if (ret != CRYPTO_SUCCESS) {
120            break;
121        }
122        mdLen = OH_CryptoDigest_GetLength(ctx);
123    } while (0);
124    OH_Crypto_FreeDataBlob(&out);
125    OH_DigestCrypto_Destroy(ctx);
126    free(testData);
127    return ret;
128}
129```
130