• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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