• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Signing and Signature Verification (C/C++)
2
3<!--Kit: Universal Keystore Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @wutiantian-gitee-->
6<!--Designer: @HighLowWorld-->
7<!--Tester: @wxy1234564846-->
8<!--Adviser: @zengyawen-->
9
10This topic walks you through on how to implement signing and signature verification using the key algorithm RSA2048, MD algorithm SHA384, and padding mode PSS. For details about the scenarios and supported algorithms, see [Supported Algorithms](huks-signing-signature-verification-overview.md#supported-algorithms).
11
12## Add the dynamic library in the CMake script.
13```txt
14target_link_libraries(entry PUBLIC libhuks_ndk.z.so)
15```
16
17## How to Develop
18
19**Key Generation**
201. Specify the key alias. For details about the naming rules, see [Key Generation Overview and Algorithm Specifications](huks-key-generation-overview.md).
21
222. Initialize the key property set.
23
243. Use [OH_Huks_GenerateKeyItem](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_generatekeyitem) to generate a key. For details, see [Key Generation Overview and Algorithm Specifications](huks-key-generation-overview.md).
25
26Alternatively, you can [import a key](huks-key-import-overview.md).
27
28**Signing**
29
301. Obtain the key alias.
31
322. Obtain the plaintext to be signed.
33
343. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset) to set algorithm parameters.
35
364. Use [OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_initsession) to initialize a key session and obtain the session handle.
37
385. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_finishsession) to end the key session and obtain the signature.
39
40**Signature Verification**
41
421. Obtain the key alias.
43
442. Obtain the signature to be verified.
45
463. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset) to [set algorithm parameters](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset).
47
484. Use [OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_initsession) to initialize a key session and obtain the session handle.
49
505. Use [OH_Huks_UpdateSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_updatesession) to update the key session.
51
526. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_finishsession) to end the key session and verify the signature.
53
54**Key Deletion**
55
56When a key is no longer used, you need to call [OH_Huks_DeleteKeyItem](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_deletekeyitem) to delete the key. For details, see [Deleting a Key](huks-delete-key-ndk.md).
57
58```c++
59#include "huks/native_huks_api.h"
60#include "huks/native_huks_param.h"
61#include "napi/native_api.h"
62#include <string.h>
63OH_Huks_Result InitParamSet(
64    struct OH_Huks_ParamSet **paramSet,
65    const struct OH_Huks_Param *params,
66    uint32_t paramCount)
67{
68    OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
69    if (ret.errorCode != OH_HUKS_SUCCESS) {
70        return ret;
71    }
72    ret = OH_Huks_AddParams(*paramSet, params, paramCount);
73    if (ret.errorCode != OH_HUKS_SUCCESS) {
74        OH_Huks_FreeParamSet(paramSet);
75        return ret;
76    }
77    ret = OH_Huks_BuildParamSet(paramSet);
78    if (ret.errorCode != OH_HUKS_SUCCESS) {
79        OH_Huks_FreeParamSet(paramSet);
80        return ret;
81    }
82    return ret;
83}
84static struct OH_Huks_Param g_genSignVerifyParamsTest[] = {
85    {
86        .tag = OH_HUKS_TAG_ALGORITHM,
87        .uint32Param = OH_HUKS_ALG_RSA
88    }, {
89        .tag = OH_HUKS_TAG_PURPOSE,
90        .uint32Param = OH_HUKS_KEY_PURPOSE_SIGN | OH_HUKS_KEY_PURPOSE_VERIFY
91    }, {
92        .tag = OH_HUKS_TAG_KEY_SIZE,
93        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
94    }, {
95        .tag = OH_HUKS_TAG_PADDING,
96        .uint32Param = OH_HUKS_PADDING_PSS
97    }, {
98        .tag = OH_HUKS_TAG_DIGEST,
99        .uint32Param = OH_HUKS_DIGEST_SHA384
100    },
101};
102static struct OH_Huks_Param g_signParamsTest[] = {
103    {
104        .tag = OH_HUKS_TAG_ALGORITHM,
105        .uint32Param = OH_HUKS_ALG_RSA
106    }, {
107        .tag = OH_HUKS_TAG_PURPOSE,
108        .uint32Param = OH_HUKS_KEY_PURPOSE_SIGN
109    }, {
110        .tag = OH_HUKS_TAG_KEY_SIZE,
111        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
112    }, {
113        .tag = OH_HUKS_TAG_PADDING,
114        .uint32Param = OH_HUKS_PADDING_PSS
115    }, {
116        .tag = OH_HUKS_TAG_DIGEST,
117        .uint32Param = OH_HUKS_DIGEST_SHA384
118    }
119};
120static struct OH_Huks_Param g_verifyParamsTest[] = {
121    {
122        .tag = OH_HUKS_TAG_ALGORITHM,
123        .uint32Param = OH_HUKS_ALG_RSA
124    }, {
125        .tag = OH_HUKS_TAG_PURPOSE,
126        .uint32Param = OH_HUKS_KEY_PURPOSE_VERIFY
127    }, {
128        .tag = OH_HUKS_TAG_KEY_SIZE,
129        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
130    }, {
131        .tag = OH_HUKS_TAG_PADDING,
132        .uint32Param = OH_HUKS_PADDING_PSS
133    }, {
134        .tag = OH_HUKS_TAG_DIGEST,
135        .uint32Param = OH_HUKS_DIGEST_SHA384
136    }
137};
138static const uint32_t RSA_COMMON_SIZE = 1024;
139static const char *g_dataToSign = "Hks_RSA_Sign_Verify_Test_0000000000000000000000000000000000000000000000000000000"
140                                    "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
141                                    "0000000000000000000000000000000000000000000000000000000000000000000000000_string";
142static napi_value SignVerifyKey(napi_env env, napi_callback_info info)
143{
144    struct OH_Huks_Blob g_keyAlias = {
145        (uint32_t)strlen("test_signVerify"),
146        (uint8_t *)"test_signVerify"
147    };
148    struct OH_Huks_Blob inData = {
149        (uint32_t)strlen(g_dataToSign),
150        (uint8_t *)g_dataToSign
151    };
152    struct OH_Huks_ParamSet *genParamSet = nullptr;
153    struct OH_Huks_ParamSet *signParamSet = nullptr;
154    struct OH_Huks_ParamSet *verifyParamSet = nullptr;
155    OH_Huks_Result ohResult;
156    do {
157        ohResult = InitParamSet(&genParamSet, g_genSignVerifyParamsTest, sizeof(g_genSignVerifyParamsTest) / sizeof(OH_Huks_Param));
158        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
159            break;
160        }
161        ohResult = InitParamSet(&signParamSet, g_signParamsTest, sizeof(g_signParamsTest) / sizeof(OH_Huks_Param));
162        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
163            break;
164        }
165        ohResult = InitParamSet(&verifyParamSet, g_verifyParamsTest, sizeof(g_verifyParamsTest) / sizeof(OH_Huks_Param));
166        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
167            break;
168        }
169        /* 1. Generate Key */
170        ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias, genParamSet, nullptr);
171        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
172            break;
173        }
174        /* 2. Sign */
175        // Init
176        uint8_t handleS[sizeof(uint64_t)] = {0};
177        struct OH_Huks_Blob handleSign = { (uint32_t)sizeof(uint64_t), handleS };
178        ohResult = OH_Huks_InitSession(&g_keyAlias, signParamSet, &handleSign, nullptr);
179        // Update
180        uint8_t outDataS[RSA_COMMON_SIZE] = {0};
181        struct OH_Huks_Blob outDataSign = { RSA_COMMON_SIZE, outDataS };
182        ohResult = OH_Huks_UpdateSession(&handleSign, signParamSet,  &inData, &outDataSign);
183        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
184            break;
185        }
186        // Finish
187        struct OH_Huks_Blob finishInData = { 0, NULL };
188        ohResult = OH_Huks_FinishSession(&handleSign, signParamSet, &finishInData, &outDataSign);
189
190        /* 3. Verify */
191        // Init
192        uint8_t handleV[sizeof(uint64_t)] = {0};
193        struct OH_Huks_Blob handleVerify = { (uint32_t)sizeof(uint64_t), handleV };
194        ohResult = OH_Huks_InitSession(&g_keyAlias, verifyParamSet, &handleVerify, nullptr);
195        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
196            break;
197        }
198        // Update loop
199        uint8_t temp[] = "out";
200        struct OH_Huks_Blob verifyOut = { (uint32_t)sizeof(temp), temp };
201        ohResult = OH_Huks_UpdateSession(&handleVerify, verifyParamSet, &inData, &verifyOut);
202        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
203            break;
204        }
205        // Finish
206        ohResult = OH_Huks_FinishSession(&handleVerify, verifyParamSet, &outDataSign, &verifyOut);
207        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
208            break;
209        }
210    } while (0);
211    (void)OH_Huks_DeleteKeyItem(&g_keyAlias, genParamSet);
212    OH_Huks_FreeParamSet(&genParamSet);
213    OH_Huks_FreeParamSet(&signParamSet);
214    OH_Huks_FreeParamSet(&verifyParamSet);
215
216    napi_value ret;
217    napi_create_int32(env, ohResult.errorCode, &ret);
218    return ret;
219}
220```
221