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