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