1# Signing and Signature Verification (C/C++)
2
3
4This 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).
5
6## Add the dynamic library in the CMake script.
7```txt
8   target_link_libraries(entry PUBLIC libhuks_ndk.z.so)
9```
10
11## How to Develop
12
13**Key Generation**
141. Set the key alias.
15
162. Initialize the key property set.
17
183. Use **OH_Huks_GenerateKeyItem** to generate a key. For details, see [Key Generation](huks-key-generation-overview.md).
19
20Alternatively, you can [import a key](huks-key-import-overview.md).
21
22**Signing**
23
241. Obtain the key alias.
25
262. Obtain the plaintext to be signed.
27
283. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_initparamset) to set algorithm parameters.
29
304. Use [OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_initsession) to initialize a key session. The session handle is returned after the initialization.
31
325. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession) to generate a signature.
33
34**Signature Verification**
35
361. Obtain the key alias.
37
382. Obtain the signature to be verified.
39
403. Set [algorithm parameters](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_initparamset).
41
424. Use [OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_initsession) to initialize a key session. The session handle is returned after the initialization.
43
445. Use [OH_Huks_UpdateSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_updatesession) to process data.
45
466. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession) to finish signature verification.
47
48**Key Deletion**
49
50Use OH_Huks_DeleteKeyItem to delete the key that is not required. For details, see [Deleting a Key](huks-delete-key-ndk.md).
51
52```c++
53#include "huks/native_huks_api.h"
54#include "huks/native_huks_param.h"
55#include <string.h>
56OH_Huks_Result InitParamSet(
57    struct OH_Huks_ParamSet **paramSet,
58    const struct OH_Huks_Param *params,
59    uint32_t paramCount)
60{
61    OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
62    if (ret.errorCode != OH_HUKS_SUCCESS) {
63        return ret;
64    }
65    ret = OH_Huks_AddParams(*paramSet, params, paramCount);
66    if (ret.errorCode != OH_HUKS_SUCCESS) {
67        OH_Huks_FreeParamSet(paramSet);
68        return ret;
69    }
70    ret = OH_Huks_BuildParamSet(paramSet);
71    if (ret.errorCode != OH_HUKS_SUCCESS) {
72        OH_Huks_FreeParamSet(paramSet);
73        return ret;
74    }
75    return ret;
76}
77static struct OH_Huks_Param g_genSignVerifyParamsTest[] = {
78    {
79        .tag = OH_HUKS_TAG_ALGORITHM,
80        .uint32Param = OH_HUKS_ALG_RSA
81    }, {
82        .tag = OH_HUKS_TAG_PURPOSE,
83        .uint32Param = OH_HUKS_KEY_PURPOSE_SIGN | OH_HUKS_KEY_PURPOSE_VERIFY
84    }, {
85        .tag = OH_HUKS_TAG_KEY_SIZE,
86        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
87    }, {
88        .tag = OH_HUKS_TAG_PADDING,
89        .uint32Param = OH_HUKS_PADDING_PSS
90    }, {
91        .tag = OH_HUKS_TAG_DIGEST,
92        .uint32Param = OH_HUKS_DIGEST_SHA384
93    },
94};
95static struct OH_Huks_Param g_signParamsTest[] = {
96    {
97        .tag = OH_HUKS_TAG_ALGORITHM,
98        .uint32Param = OH_HUKS_ALG_RSA
99    }, {
100        .tag = OH_HUKS_TAG_PURPOSE,
101        .uint32Param = OH_HUKS_KEY_PURPOSE_SIGN
102    }, {
103        .tag = OH_HUKS_TAG_KEY_SIZE,
104        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
105    }, {
106        .tag = OH_HUKS_TAG_PADDING,
107        .uint32Param = OH_HUKS_PADDING_PSS
108    }, {
109        .tag = OH_HUKS_TAG_DIGEST,
110        .uint32Param = OH_HUKS_DIGEST_SHA384
111    }
112};
113static struct OH_Huks_Param g_verifyParamsTest[] = {
114    {
115        .tag = OH_HUKS_TAG_ALGORITHM,
116        .uint32Param = OH_HUKS_ALG_RSA
117    }, {
118        .tag = OH_HUKS_TAG_PURPOSE,
119        .uint32Param = OH_HUKS_KEY_PURPOSE_VERIFY
120    }, {
121        .tag = OH_HUKS_TAG_KEY_SIZE,
122        .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048
123    }, {
124        .tag = OH_HUKS_TAG_PADDING,
125        .uint32Param = OH_HUKS_PADDING_PSS
126    }, {
127        .tag = OH_HUKS_TAG_DIGEST,
128        .uint32Param = OH_HUKS_DIGEST_SHA384
129    }
130};
131static const uint32_t RSA_COMMON_SIZE = 1024;
132static const char *g_dataToSign = "Hks_RSA_Sign_Verify_Test_0000000000000000000000000000000000000000000000000000000"
133                                    "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
134                                    "0000000000000000000000000000000000000000000000000000000000000000000000000_string";
135static napi_value SignVerifyKey(napi_env env, napi_callback_info info)
136{
137    struct OH_Huks_Blob g_keyAlias = {
138        (uint32_t)strlen("test_signVerify"),
139        (uint8_t *)"test_signVerify"
140    };
141    struct OH_Huks_Blob inData = {
142        (uint32_t)strlen(g_dataToSign),
143        (uint8_t *)g_dataToSign
144    };
145    struct OH_Huks_ParamSet *genParamSet = nullptr;
146    struct OH_Huks_ParamSet *signParamSet = nullptr;
147    struct OH_Huks_ParamSet *verifyParamSet = nullptr;
148    OH_Huks_Result ohResult;
149    do {
150        ohResult = InitParamSet(&genParamSet, g_genSignVerifyParamsTest, sizeof(g_genSignVerifyParamsTest) / sizeof(OH_Huks_Param));
151        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
152            break;
153        }
154        ohResult = InitParamSet(&signParamSet, g_signParamsTest, sizeof(g_signParamsTest) / sizeof(OH_Huks_Param));
155        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
156            break;
157        }
158        ohResult = InitParamSet(&verifyParamSet, g_verifyParamsTest, sizeof(g_verifyParamsTest) / sizeof(OH_Huks_Param));
159        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
160            break;
161        }
162        /* 1. Generate Key */
163        ohResult = OH_Huks_GenerateKeyItem(&g_keyAlias, genParamSet, nullptr);
164        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
165            break;
166        }
167        /* 2. Sign */
168        // Init
169        uint8_t handleS[sizeof(uint64_t)] = {0};
170        struct OH_Huks_Blob handleSign = { (uint32_t)sizeof(uint64_t), handleS };
171        ohResult = OH_Huks_InitSession(&g_keyAlias, signParamSet, &handleSign, nullptr);
172        // Update
173        uint8_t outDataS[RSA_COMMON_SIZE] = {0};
174        struct OH_Huks_Blob outDataSign = { RSA_COMMON_SIZE, outDataS };
175        ohResult = OH_Huks_UpdateSession(&handleSign, signParamSet,  &inData, &outDataSign);
176        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
177            break;
178        }
179        // Finish
180        struct OH_Huks_Blob finishInData = { 0, NULL };
181        ohResult = OH_Huks_FinishSession(&handleSign, signParamSet, &finishInData, &outDataSign);
182
183        /* 3. Verify */
184        // Init
185        uint8_t handleV[sizeof(uint64_t)] = {0};
186        struct OH_Huks_Blob handleVerify = { (uint32_t)sizeof(uint64_t), handleV };
187        ohResult = OH_Huks_InitSession(&g_keyAlias, verifyParamSet, &handleVerify, nullptr);
188        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
189            break;
190        }
191        // Update loop
192        uint8_t temp[] = "out";
193        struct OH_Huks_Blob verifyOut = { (uint32_t)sizeof(temp), temp };
194        ohResult = OH_Huks_UpdateSession(&handleVerify, verifyParamSet, &inData, &verifyOut);
195        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
196            break;
197        }
198        // Finish
199        ohResult = OH_Huks_FinishSession(&handleVerify, verifyParamSet, &outDataSign, &verifyOut);
200        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
201            break;
202        }
203    } while (0);
204    (void)OH_Huks_DeleteKeyItem(&g_keyAlias, genParamSet);
205    OH_Huks_FreeParamSet(&genParamSet);
206    OH_Huks_FreeParamSet(&signParamSet);
207    OH_Huks_FreeParamSet(&verifyParamSet);
208
209    napi_value ret;
210    napi_create_int32(env, ohResult.errorCode, &ret);
211    return ret;
212}
213```
214