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