• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Encryption and Decryption with an AES Symmetric Key (GCM Mode) (C/C++)
2
3<!--Kit: Crypto Architecture Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @zxz--3-->
6<!--Designer: @lanming-->
7<!--Tester: @PAFT-->
8<!--Adviser: @zengyawen-->
9
10For details about the algorithm specifications, see [AES](crypto-sym-encrypt-decrypt-spec.md#aes).
11
12## Adding the Dynamic Library in the CMake Script
13```txt
14target_link_libraries(entry PUBLIC libohcrypto.so)
15```
16
17## How to Develop
18
19**Creating an Object**
20
21Call [OH_CryptoSymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_create) and [OH_CryptoSymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_generate) to generate a symmetric key (**OH_CryptoSymKey**) with the key algorithm being AES and the key length being 128 bits.
22
23   Generate an AES symmetric key as instructed by the following example. For details, see [Symmetric Key Generation and Conversion Specifications: AES](crypto-sym-key-generation-conversion-spec.md#aes) and [Randomly Generating a Symmetric Key](crypto-generate-sym-key-randomly-ndk.md). Note that the input parameters in the reference document may be different from those in the example.
24
251. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_create) with the string parameter **'AES128|GCM|PKCS7'** to create a **Cipher** instance for encryption. The key type is **AES128**, block cipher mode is **GCM**, and the padding mode is **PKCS7**.
26
272. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_create) to create a parameter object and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_setparam) to set encryption parameters.
28
293. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_ENCRYPT_MODE**, and specify the symmetric key (**OH_CryptoSymKey**) and the encryption parameter instance (**OH_CryptoSymCipherParams**) corresponding to the GCM mode.
30
314. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in plaintext).
32
33   Currently, the amount of data to be passed in by a single **OH_CryptoSymCipher_Update** is not limited. You can determine how to pass in data based on the data volume.
34
35   - If a small amount of data is to be encrypted, you can use **OH_CryptoSymCipher_Final()** immediately after **OH_CryptoSymCipher_Init()**.
36   - If a large amount of data is to be encrypted, you can call **OH_CryptoSymCipher_Update()** multiple times to [pass in the data by segment](crypto-aes-sym-encrypt-decrypt-gcm-by-segment-ndk.md).
37
385. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the encrypted data.
39   - If data has been passed in by **OH_CryptoSymCipher_Update()**, pass in **null** in the **data** parameter of **OH_CryptoSymCipher_Final**.
40   - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data.
41
42   > **NOTE**<br>
43   > If GCM mode is used, **authTag** returned by **OH_CryptoSymCipher_Final()** will be used to initialize the authentication information during decryption and needs to be saved. In GCM mode, the algorithm library currently supports only the 16-byte **authTag**. In the following example, **authTag** is of 16 bytes.
44
45
46**Decrypting a Message**
47
481. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_create) with the string parameter **'AES128|GCM|PKCS7'** to create a **Cipher** instance for decryption. The key type is **AES128**, block cipher mode is **GCM**, and the padding mode is **PKCS7**.
49
502. Call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_setparam) to set **authTag** as the authentication information for decryption.
51
523. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_DECRYPT_MODE**, and specify the decryption key (**OH_CryptoSymKey**) and the decryption parameter instance (**OH_CryptoSymCipherParams**) corresponding to the GCM mode.
53
544. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in ciphertext).
55
565. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the decrypted data.
57
58**Destroying Objects**
59
60Call [OH_CryptoSymKeyGenerator_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkeygenerator_destroy), [OH_CryptoSymCipher_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_destroy), and [OH_CryptoSymCipherParams_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipherparams_destroy) to destroy the object.
61
62- **Example**
63
64```c++
65#include "CryptoArchitectureKit/crypto_common.h"
66#include "CryptoArchitectureKit/crypto_sym_cipher.h"
67#include <string.h>
68
69static OH_Crypto_ErrCode doTestAesGcm()
70{
71    OH_CryptoSymKeyGenerator *genCtx = nullptr;
72    OH_CryptoSymCipher *encCtx = nullptr;
73    OH_CryptoSymCipher *decCtx = nullptr;
74    OH_CryptoSymKey *keyCtx = nullptr;
75    OH_CryptoSymCipherParams *params = nullptr;
76
77    Crypto_DataBlob encData = {.data = nullptr, .len = 0};
78    Crypto_DataBlob decData = {.data = nullptr, .len = 0};
79
80    uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8};
81    uint8_t tag[16] = {0};
82    uint8_t iv[12] = {1, 2, 4, 12, 3, 4, 2, 3, 3, 2, 0, 4}; // iv is generated from an array of secure random numbers.
83    Crypto_DataBlob ivData = {.data = iv, .len = sizeof(iv)};
84    Crypto_DataBlob aadData = {.data = aad, .len = sizeof(aad)};
85    Crypto_DataBlob tagData = {.data = tag, .len = sizeof(tag)};
86    Crypto_DataBlob tagOutPut = {.data = nullptr, .len = 0};
87    char *plainText = const_cast<char *>("this is test!");
88    Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)};
89
90    // Generate a symmetric key.
91    OH_Crypto_ErrCode ret;
92    ret = OH_CryptoSymKeyGenerator_Create("AES128", &genCtx);
93    if (ret != CRYPTO_SUCCESS) {
94        goto end;
95    }
96    ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx);
97    if (ret != CRYPTO_SUCCESS) {
98        goto end;
99    }
100
101    // Set parameters.
102    ret = OH_CryptoSymCipherParams_Create(&params);
103    if (ret != CRYPTO_SUCCESS) {
104        goto end;
105    }
106    ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivData);
107    if (ret != CRYPTO_SUCCESS) {
108        goto end;
109    }
110    ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadData);
111    if (ret != CRYPTO_SUCCESS) {
112        goto end;
113    }
114    ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagData);
115    if (ret != CRYPTO_SUCCESS) {
116        goto end;
117    }
118
119    // Encrypt the message.
120    ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &encCtx);
121    if (ret != CRYPTO_SUCCESS) {
122        goto end;
123    }
124    ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params);
125    if (ret != CRYPTO_SUCCESS) {
126        goto end;
127    }
128    ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &encData);
129    if (ret != CRYPTO_SUCCESS) {
130        goto end;
131    }
132    ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tagOutPut);
133    if (ret != CRYPTO_SUCCESS) {
134        goto end;
135    }
136
137    // Decrypt the message.
138    ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &decCtx);
139    if (ret != CRYPTO_SUCCESS) {
140        goto end;
141    }
142    ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagOutPut);
143    if (ret != CRYPTO_SUCCESS) {
144        goto end;
145    }
146    ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params);
147    if (ret != CRYPTO_SUCCESS) {
148        goto end;
149    }
150    ret = OH_CryptoSymCipher_Update(decCtx, &encData, &decData);
151    if (ret != CRYPTO_SUCCESS) {
152        goto end;
153    }
154    ret = OH_CryptoSymCipher_Final(decCtx, nullptr, &decData);
155    if (ret != CRYPTO_SUCCESS) {
156        goto end;
157    }
158
159end:
160    OH_CryptoSymCipherParams_Destroy(params);
161    OH_CryptoSymCipher_Destroy(encCtx);
162    OH_CryptoSymCipher_Destroy(decCtx);
163    OH_CryptoSymKeyGenerator_Destroy(genCtx);
164    OH_CryptoSymKey_Destroy(keyCtx);
165    OH_Crypto_FreeDataBlob(&encData);
166    OH_Crypto_FreeDataBlob(&decData);
167    OH_Crypto_FreeDataBlob(&tagOutPut);
168    return ret;
169}
170```
171