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