• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params);
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