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