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