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