1# Encryption and Decryption with an AES Symmetric Key (GCM Mode) (C/C++) 2 3 4For details about the algorithm specifications, see [AES](crypto-sym-encrypt-decrypt-spec.md#aes). 5 6 7## Adding the Dynamic Library in the CMake Script 8```txt 9target_link_libraries(entry PUBLIC libohcrypto.so) 10``` 11 12## How to Develop 13 14**Creating an Object** 15 16Call [OH_CryptoSymKeyGenerator_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_create) and [OH_CryptoSymKeyGenerator_Generate](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_generate) to generate a 128-bit AES symmetric key (**OH_CryptoSymKey**). 17 18In addition to the example in this topic, [AES](crypto-sym-key-generation-conversion-spec.md#aes) and [Randomly Generating a Symmetric Key](crypto-generate-sym-key-randomly-ndk.md) may help you better understand how to generate an AES symmetric key. Note that the input parameters in the reference documents may be different from those in the example below. 19 20**Encrypting a Message** 21 221. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.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**. 23 242. Call [OH_CryptoSymCipherParams_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_create) to create a symmetric cipher parameter instance, and call [OH_CryptoSymCipherParams_SetParam](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam) to set cipher parameters. 25 263. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_ENCRYPT_MODE**, and specify the key for encryption (**OH_CryptoSymKey**) and the encryption parameter instance (**OH_CryptoSymCipherParams**) corresponding to the GCM mode. 27 284. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update) to update the data (plaintext) to be encrypted. 29 30 Currently, the amount of data to be passed in by a single **update()** is not limited. You can determine how to pass in data based on the data volume. 31 32 - If a small amount of data is to be encrypted, you can use **OH_CryptoSymCipher_Final()** immediately after **OH_CryptoSymCipher_Init()**. 33 - 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. 34 355. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final) to generate the ciphertext. 36 - If data has been passed in by **OH_CryptoSymCipher_Update()**, pass in **null** in the **data** parameter of **OH_CryptoSymCipher_Final**. 37 - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 38 > **NOTE** 39 > 40 > - 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. 41 > 42 > - In GCM mode, **authTag** must be of 16 bytes. It is used as the authentication information during decryption. In the following example, **authTag** is of 16 bytes. 43 44 45 46**Decrypting a Message** 47 481. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.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/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_setparam) to set **authTag** as the authentication information for decryption. 51 523. Call [OH_CryptoSymCipher_Init](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_init) to initialize the **Cipher** instance. Specifically, set **mode** to **CRYPTO_DECRYPT_MODE**, and specify the key for decryption (**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/_crypto_sym_cipher_api.md#oh_cryptosymcipher_update) to update the data (ciphertext) to be decrypted. 55 565. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_final) to generate the plaintext. 57 58**Destroying Objects** 59 60Call [OH_CryptoSymKeyGenerator_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_key_api.md#oh_cryptosymkeygenerator_destroy), [OH_CryptoSymCipher_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipher_destroy), and [OH_CryptoSymCipherParams_Destroy](../../reference/apis-crypto-architecture-kit/_crypto_sym_cipher_api.md#oh_cryptosymcipherparams_destroy) to destroy the instances created. 61 62 63**Example ** 64 65```c++ 66#include "CryptoArchitectureKit/crypto_common.h" 67#include "CryptoArchitectureKit/crypto_sym_cipher.h" 68#include <string.h> 69 70static OH_Crypto_ErrCode doTestAesGcm() 71{ 72 OH_CryptoSymKeyGenerator *genCtx = nullptr; 73 OH_CryptoSymCipher *encCtx = nullptr; 74 OH_CryptoSymCipher *decCtx = nullptr; 75 OH_CryptoSymKey *keyCtx = nullptr; 76 OH_CryptoSymCipherParams *params = nullptr; 77 78 Crypto_DataBlob encData = {.data = nullptr, .len = 0}; 79 Crypto_DataBlob decData = {.data = nullptr, .len = 0}; 80 81 uint8_t aad[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 82 uint8_t tag[16] = {0}; 83 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. 84 Crypto_DataBlob ivData = {.data = iv, .len = sizeof(iv)}; 85 Crypto_DataBlob aadData = {.data = aad, .len = sizeof(aad)}; 86 Crypto_DataBlob tagData = {.data = tag, .len = sizeof(tag)}; 87 Crypto_DataBlob tagOutPut = {.data = nullptr, .len = 0}; 88 char *plainText = const_cast<char *>("this is test!"); 89 Crypto_DataBlob msgBlob = {.data = (uint8_t *)(plainText), .len = strlen(plainText)}; 90 91 // Generate a symmetric key. 92 OH_Crypto_ErrCode ret; 93 ret = OH_CryptoSymKeyGenerator_Create("AES128", &genCtx); 94 if (ret != CRYPTO_SUCCESS) { 95 goto end; 96 } 97 ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx); 98 if (ret != CRYPTO_SUCCESS) { 99 goto end; 100 } 101 102 // Set parameters. 103 ret = OH_CryptoSymCipherParams_Create(¶ms); 104 if (ret != CRYPTO_SUCCESS) { 105 goto end; 106 } 107 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivData); 108 if (ret != CRYPTO_SUCCESS) { 109 goto end; 110 } 111 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_AAD_DATABLOB, &aadData); 112 if (ret != CRYPTO_SUCCESS) { 113 goto end; 114 } 115 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagData); 116 if (ret != CRYPTO_SUCCESS) { 117 goto end; 118 } 119 120 // Encrypt data. 121 ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &encCtx); 122 if (ret != CRYPTO_SUCCESS) { 123 goto end; 124 } 125 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params); 126 if (ret != CRYPTO_SUCCESS) { 127 goto end; 128 } 129 ret = OH_CryptoSymCipher_Update(encCtx, &msgBlob, &encData); 130 if (ret != CRYPTO_SUCCESS) { 131 goto end; 132 } 133 ret = OH_CryptoSymCipher_Final(encCtx, nullptr, &tagOutPut); 134 if (ret != CRYPTO_SUCCESS) { 135 goto end; 136 } 137 138 // Decrypt data. 139 ret = OH_CryptoSymCipher_Create("AES128|GCM|PKCS7", &decCtx); 140 if (ret != CRYPTO_SUCCESS) { 141 goto end; 142 } 143 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_TAG_DATABLOB, &tagOutPut); 144 if (ret != CRYPTO_SUCCESS) { 145 goto end; 146 } 147 ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, params); 148 if (ret != CRYPTO_SUCCESS) { 149 goto end; 150 } 151 ret = OH_CryptoSymCipher_Update(decCtx, &encData, &decData); 152 if (ret != CRYPTO_SUCCESS) { 153 goto end; 154 } 155 ret = OH_CryptoSymCipher_Final(decCtx, nullptr, &decData); 156 if (ret != CRYPTO_SUCCESS) { 157 goto end; 158 } 159 160end: 161 OH_CryptoSymCipherParams_Destroy(params); 162 OH_CryptoSymCipher_Destroy(encCtx); 163 OH_CryptoSymCipher_Destroy(decCtx); 164 OH_CryptoSymKeyGenerator_Destroy(genCtx); 165 OH_CryptoSymKey_Destroy(keyCtx); 166 OH_Crypto_FreeDataBlob(&encData); 167 OH_Crypto_FreeDataBlob(&decData); 168 OH_Crypto_FreeDataBlob(&tagOutPut); 169 return ret; 170} 171``` 172