1# Encryption and Decryption with a 3DES Asymmetric Key Pair (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 [3DES](crypto-sym-encrypt-decrypt-spec.md#3des). 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 3DES and the key length being 192 bits. 22 23 In addition to the example in this topic, [3DES](crypto-sym-key-generation-conversion-spec.md#3des) and [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key-ndk.md) may help you better understand how to generate a 3DES symmetric key pair. Note that the input parameters in the reference documents may be different from those in the example below. 24 25**Encrypting a Message** 26 271. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_create) with the string parameter **'3DES192|ECB|PKCS7'** to create a **Cipher** instance for encryption. The key type is **3DES192**, block cipher mode is **ECB**, and the padding mode is **PKCS7**. 28 292. 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 key for encryption (**OH_CryptoSymKey**). 30 31 If ECB mode is used, set **params** to **null**. 32 333. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in plaintext). 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. 37 384. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the encrypted data. 39 40 - If **OH_CryptoSymCipher_Update** is used to pass in data, set **data** to **null**. If **OH_CryptoSymCipher_Final** is used to pass in data, pass in the plaintext via **data**. 41 - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 42 43**Decryption** 44 451. Call [OH_CryptoSymCipher_Create](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_create) with the string parameter **'3DES192|ECB|PKCS7'** to create a **Cipher** instance for decryption. The key type is **3DES192**, block cipher mode is **ECB**, and the padding mode is **PKCS7**. 46 472. 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 key for decryption (**OH_CryptoSymKey**). If ECB mode is used, pass **null**. 48 493. Call [OH_CryptoSymCipher_Update](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_update) to update data (in ciphertext). 50 51 - If a small amount of data is to be encrypted, you can use **OH_CryptoSymCipher_Final()** immediately after **OH_CryptoSymCipher_Init()**. 52 - 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. 53 - You can determine the operation mode based on the data size. For example, if the data size exceeds 20, call **OH_CryptoSymCipher_Update**. 54 554. Call [OH_CryptoSymCipher_Final](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-cipher-h.md#oh_cryptosymcipher_final) to obtain the decrypted data. 56 57 - If **OH_CryptoSymCipher_Update** is used to pass in data, set **data** to **null**. If **OH_CryptoSymCipher_Final** is used to pass in data, pass in the ciphertext via **data**. 58 - The output of **OH_CryptoSymCipher_Final** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 59 60**Destroying Objects** 61 62Call [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), [OH_CryptoSymKey_Destroy](../../reference/apis-crypto-architecture-kit/capi-crypto-sym-key-h.md#oh_cryptosymkey_destroy), and [OH_Crypto_FreeDataBlob](../../reference/apis-crypto-architecture-kit/capi-crypto-common-h.md#oh_crypto_freedatablob) to release the allocated memory and destroy the object. 63 64## Example 65 66If the cipher mode is ECB, you do not need to set encryption and decryption parameters. 67 68If the CBC, CTR, OFB, or CFB block cipher mode is used, you need to set the **iv** parameter for encryption and decryption. For details, see [Setting the IV](#setting-the-iv). You need to modify related parameters when generating and initializing the **Cipher** instance during encryption or decryption. 69 70```c++ 71#include "CryptoArchitectureKit/crypto_common.h" 72#include "CryptoArchitectureKit/crypto_sym_cipher.h" 73#include <string.h> 74 75static OH_Crypto_ErrCode doTest3DesEcb() 76{ 77 OH_CryptoSymKeyGenerator *genCtx = nullptr; 78 OH_CryptoSymCipher *encCtx = nullptr; 79 OH_CryptoSymCipher *decCtx = nullptr; 80 OH_CryptoSymKey *keyCtx = nullptr; 81 char *plainText = const_cast<char *>("this is test!"); 82 Crypto_DataBlob input = {.data = (uint8_t *)(plainText), .len = strlen(plainText)}; 83 Crypto_DataBlob encData = {.data = nullptr, .len = 0}; 84 Crypto_DataBlob decData = {.data = nullptr, .len = 0}; 85 86 // Generate a symmetric key randomly. 87 OH_Crypto_ErrCode ret; 88 ret = OH_CryptoSymKeyGenerator_Create("3DES192", &genCtx); 89 if (ret != CRYPTO_SUCCESS) { 90 goto end; 91 } 92 ret = OH_CryptoSymKeyGenerator_Generate(genCtx, &keyCtx); 93 if (ret != CRYPTO_SUCCESS) { 94 goto end; 95 } 96 97 // Encrypt the message. 98 ret = OH_CryptoSymCipher_Create("3DES192|ECB|PKCS7", &encCtx); 99 if (ret != CRYPTO_SUCCESS) { 100 goto end; 101 } 102 // If CBC, CTR, OFB, or CFB is used, modify the cipher mode and set the IV. 103 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, nullptr); 104 if (ret != CRYPTO_SUCCESS) { 105 goto end; 106 } 107 ret = OH_CryptoSymCipher_Final(encCtx, &input, &encData); 108 if (ret != CRYPTO_SUCCESS) { 109 goto end; 110 } 111 112 // Decrypt the message. 113 ret = OH_CryptoSymCipher_Create("3DES192|ECB|PKCS7", &decCtx); 114 if (ret != CRYPTO_SUCCESS) { 115 goto end; 116 } 117 // If CBC, CTR, OFB, or CFB is used, modify the cipher mode and set the IV. 118 ret = OH_CryptoSymCipher_Init(decCtx, CRYPTO_DECRYPT_MODE, keyCtx, nullptr); 119 if (ret != CRYPTO_SUCCESS) { 120 goto end; 121 } 122 ret = OH_CryptoSymCipher_Final(decCtx, &encData, &decData); 123 if (ret != CRYPTO_SUCCESS) { 124 goto end; 125 } 126 127end: 128 OH_CryptoSymCipher_Destroy(encCtx); 129 OH_CryptoSymCipher_Destroy(decCtx); 130 OH_CryptoSymKeyGenerator_Destroy(genCtx); 131 OH_CryptoSymKey_Destroy(keyCtx); 132 OH_Crypto_FreeDataBlob(&encData); 133 OH_Crypto_FreeDataBlob(&decData); 134 return ret; 135} 136``` 137 138### Setting the IV 139 140The following example demonstrates how to set the IV when the CBC mode is used. 141 142If CBC, CTR, OFB, or CFB mode is used, set the IV in the same way. In ECB mode, you don't need to set this parameter. 143 144```c++ 145 OH_CryptoSymCipherParams *params = nullptr; 146 uint8_t iv[8] = {1, 2, 4, 12, 3, 4, 2, 3}; // iv is generated from an array of secure random numbers. 147 Crypto_DataBlob ivBlob = {.data = iv, .len = sizeof(iv)}; 148 149 ret = OH_CryptoSymCipherParams_Create(¶ms); 150 if (ret != CRYPTO_SUCCESS) { 151 goto end; 152 } 153 // Set parameters. 154 ret = OH_CryptoSymCipherParams_SetParam(params, CRYPTO_IV_DATABLOB, &ivBlob); // You only need to set iv if CBC mode is used. 155 if (ret != CRYPTO_SUCCESS) { 156 goto end; 157 } 158 159 // Encrypt data. 160 ret = OH_CryptoSymCipher_Create("3DES192|CBC|PKCS7", &encCtx); 161 if (ret != CRYPTO_SUCCESS) { 162 goto end; 163 } 164 ret = OH_CryptoSymCipher_Init(encCtx, CRYPTO_ENCRYPT_MODE, keyCtx, params); 165 if (ret != CRYPTO_SUCCESS) { 166 goto end; 167 } 168 // This code snippet only shows the differences between CBC, CTR, OFB, and CFB modes. For details about other processes, see the related development examples. 169``` 170