1# Encryption and Decryption (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 10The topic uses a 256-bit AES key as an example to describe how to encrypt and decrypt data. For details about the scenarios and supported algorithms, see [Supported Algorithms](huks-key-generation-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## How to Develop 17 18**Key Generation** 19 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**Encryption** 29 301. Obtain the key alias. 31 322. Obtain the data to be encrypted. 33 343. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset) to set algorithm parameters. If AES is used for encryption, the cipher mode and padding mode must be specified. In the following example, the cipher mode is **CBC** and the padding mode is **PKCS7**. In this case, the IV must be set. 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 finish the key session and obtain the encrypted ciphertext. 39 40**Decryption** 41 421. Obtain the key alias. 43 442. Obtain the ciphertext to be decrypted. 45 463. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset) to set algorithm parameters. If AES is used for decryption, the cipher mode and padding mode must be specified. In the following example, the cipher mode is CBC and the padding mode is PKCS7. In this case, the IV must be set. 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_FinishSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_finishsession) to finish the key session and obtain the decrypted data. 51 52**Key Deletion** 53 54Use **OH_Huks_DeleteKeyItem** to delete the key that is not required. For details, see [Deleting a Key](huks-delete-key-ndk.md). 55 56```c++ 57#include "huks/native_huks_api.h" 58#include "huks/native_huks_param.h" 59#include "napi/native_api.h" 60#include <string.h> 61OH_Huks_Result InitParamSet( 62 struct OH_Huks_ParamSet **paramSet, 63 const struct OH_Huks_Param *params, 64 uint32_t paramCount) 65{ 66 OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 67 if (ret.errorCode != OH_HUKS_SUCCESS) { 68 return ret; 69 } 70 ret = OH_Huks_AddParams(*paramSet, params, paramCount); 71 if (ret.errorCode != OH_HUKS_SUCCESS) { 72 OH_Huks_FreeParamSet(paramSet); 73 return ret; 74 } 75 ret = OH_Huks_BuildParamSet(paramSet); 76 if (ret.errorCode != OH_HUKS_SUCCESS) { 77 OH_Huks_FreeParamSet(paramSet); 78 return ret; 79 } 80 return ret; 81} 82static const uint32_t IV_SIZE = 16; 83static uint8_t IV[IV_SIZE] = { 0 }; // this is a test value, for real use the iv should be different every time. 84static struct OH_Huks_Param g_genEncDecParams[] = { 85 { 86 .tag = OH_HUKS_TAG_ALGORITHM, 87 .uint32Param = OH_HUKS_ALG_AES 88 }, { 89 .tag = OH_HUKS_TAG_PURPOSE, 90 .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT | OH_HUKS_KEY_PURPOSE_DECRYPT 91 }, { 92 .tag = OH_HUKS_TAG_KEY_SIZE, 93 .uint32Param = OH_HUKS_AES_KEY_SIZE_256 94 }, { 95 .tag = OH_HUKS_TAG_PADDING, 96 .uint32Param = OH_HUKS_PADDING_NONE 97 }, { 98 .tag = OH_HUKS_TAG_BLOCK_MODE, 99 .uint32Param = OH_HUKS_MODE_CBC 100 } 101}; 102static struct OH_Huks_Param g_encryptParams[] = { 103 { 104 .tag = OH_HUKS_TAG_ALGORITHM, 105 .uint32Param = OH_HUKS_ALG_AES 106 }, { 107 .tag = OH_HUKS_TAG_PURPOSE, 108 .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT 109 }, { 110 .tag = OH_HUKS_TAG_KEY_SIZE, 111 .uint32Param = OH_HUKS_AES_KEY_SIZE_256 112 }, { 113 .tag = OH_HUKS_TAG_PADDING, 114 .uint32Param = OH_HUKS_PADDING_NONE 115 }, { 116 .tag = OH_HUKS_TAG_BLOCK_MODE, 117 .uint32Param = OH_HUKS_MODE_CBC 118 }, { 119 .tag = OH_HUKS_TAG_IV, 120 .blob = { 121 .size = IV_SIZE, 122 .data = (uint8_t *)IV // this is a test value, for real use the iv should be different every time. 123 } 124 } 125}; 126static struct OH_Huks_Param g_decryptParams[] = { 127 { 128 .tag = OH_HUKS_TAG_ALGORITHM, 129 .uint32Param = OH_HUKS_ALG_AES 130 }, { 131 .tag = OH_HUKS_TAG_PURPOSE, 132 .uint32Param = OH_HUKS_KEY_PURPOSE_DECRYPT 133 }, { 134 .tag = OH_HUKS_TAG_KEY_SIZE, 135 .uint32Param = OH_HUKS_AES_KEY_SIZE_256 136 }, { 137 .tag = OH_HUKS_TAG_PADDING, 138 .uint32Param = OH_HUKS_PADDING_NONE 139 }, { 140 .tag = OH_HUKS_TAG_BLOCK_MODE, 141 .uint32Param = OH_HUKS_MODE_CBC 142 }, { 143 .tag = OH_HUKS_TAG_IV, 144 .blob = { 145 .size = IV_SIZE, 146 .data = (uint8_t *)IV // this is a test value, for real use the iv should be different every time. 147 } 148 } 149}; 150static const uint32_t AES_COMMON_SIZE = 1024; 151OH_Huks_Result HksAesCipherTestEncrypt( 152 const struct OH_Huks_Blob *keyAlias, 153 const struct OH_Huks_ParamSet *encryptParamSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *cipherText) 154{ 155 uint8_t handleE[sizeof(uint64_t)] = {0}; 156 struct OH_Huks_Blob handleEncrypt = {sizeof(uint64_t), handleE}; 157 OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, encryptParamSet, &handleEncrypt, nullptr); 158 if (ret.errorCode != OH_HUKS_SUCCESS) { 159 return ret; 160 } 161 ret = OH_Huks_FinishSession(&handleEncrypt, encryptParamSet, inData, cipherText); 162 return ret; 163} 164OH_Huks_Result HksAesCipherTestDecrypt( 165 const struct OH_Huks_Blob *keyAlias, 166 const struct OH_Huks_ParamSet *decryptParamSet, const struct OH_Huks_Blob *cipherText, struct OH_Huks_Blob *plainText, 167 const struct OH_Huks_Blob *inData) 168{ 169 uint8_t handleD[sizeof(uint64_t)] = {0}; 170 struct OH_Huks_Blob handleDecrypt = {sizeof(uint64_t), handleD}; 171 OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, decryptParamSet, &handleDecrypt, nullptr); 172 if (ret.errorCode != OH_HUKS_SUCCESS) { 173 return ret; 174 } 175 ret = OH_Huks_FinishSession(&handleDecrypt, decryptParamSet, cipherText, plainText); 176 return ret; 177} 178static napi_value EncDecKey(napi_env env, napi_callback_info info) 179{ 180 char tmpKeyAlias[] = "test_enc_dec"; 181 struct OH_Huks_Blob keyAlias = { (uint32_t)strlen(tmpKeyAlias), (uint8_t *)tmpKeyAlias }; 182 struct OH_Huks_ParamSet *genParamSet = nullptr; 183 struct OH_Huks_ParamSet *encryptParamSet = nullptr; 184 struct OH_Huks_ParamSet *decryptParamSet = nullptr; 185 OH_Huks_Result ohResult; 186 do { 187 /* 1. Generate Key */ 188 /* 189 * Simulate the key generation scenario. 190 * 1.1. Set the key alias. 191 */ 192 /* 193 * 1.2. Obtain the parameters for key generation. 194 */ 195 ohResult = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(OH_Huks_Param)); 196 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 197 break; 198 } 199 /* 200 * 1.3. Call generateKeyItem to generate a key. 201 */ 202 ohResult = OH_Huks_GenerateKeyItem(&keyAlias, genParamSet, nullptr); 203 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 204 break; 205 } 206 /* 2. Encrypt */ 207 /* 208 * Simulate the encryption scenario. 209 * 2.1. Obtain the key alias. 210 */ 211 /* 212 * 2.2. Obtain the data to be encrypted. 213 */ 214 /* 215 * 2.3. Obtain the algorithm parameters for encryption. 216 */ 217 ohResult = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(OH_Huks_Param)); 218 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 219 break; 220 } 221 char tmpInData[] = "AES_ECB_INDATA_1"; 222 struct OH_Huks_Blob inData = { (uint32_t)strlen(tmpInData), (uint8_t *)tmpInData }; 223 uint8_t cipher[AES_COMMON_SIZE] = {0}; 224 struct OH_Huks_Blob cipherText = {AES_COMMON_SIZE, cipher}; 225 /* 226 * 2.4. Call initSession to obtain a session handle. 227 */ 228 /* 229 * 2.5. Call finishSession to obtain the ciphertext. 230 */ 231 ohResult = HksAesCipherTestEncrypt(&keyAlias, encryptParamSet, &inData, &cipherText); 232 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 233 break; 234 } 235 /* 3. Decrypt */ 236 /* 237 * Simulate the decryption scenario. 238 * 3.1. Obtain the key alias. 239 */ 240 /* 241 * 3.2. Obtain the ciphertext to be decrypted. 242 */ 243 /* 244 * 3.3 Obtain the algorithm parameters for decryption. 245 */ 246 ohResult = InitParamSet(&decryptParamSet, g_decryptParams, sizeof(g_decryptParams) / sizeof(OH_Huks_Param)); 247 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 248 break; 249 } 250 uint8_t plain[AES_COMMON_SIZE] = {0}; 251 struct OH_Huks_Blob plainText = {AES_COMMON_SIZE, plain}; 252 /* 253 * 3.4. Call initSession to obtain a session handle. 254 */ 255 /* 256 * 3.5. Call finishSession to obtain the decrypted data. 257 */ 258 ohResult = HksAesCipherTestDecrypt(&keyAlias, decryptParamSet, &cipherText, &plainText, &inData); 259 } while (0); 260 /* 4. Delete Key */ 261 /* 262 * Simulate the key deletion scenario. 263 * 4.1. Obtain the key alias. 264 */ 265 /* 266 * 4.2. Call deleteKeyItem to delete the key. 267 */ 268 (void)OH_Huks_DeleteKeyItem(&keyAlias, genParamSet); 269 270 OH_Huks_FreeParamSet(&genParamSet); 271 OH_Huks_FreeParamSet(&encryptParamSet); 272 OH_Huks_FreeParamSet(&decryptParamSet); 273 274 napi_value ret; 275 napi_create_int32(env, ohResult.errorCode, &ret); 276 return ret; 277} 278``` 279