• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Encryption and Decryption with a 3DES Asymmetric Key Pair (ArkTS)
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## How to Develop
13
14**Encryption**
15
161. Call [cryptoFramework.createSymKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesymkeygenerator) and [SymKeyGenerator.convertKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#convertkey-1) to generate a 192-bit 3DES symmetric key (**SymKey**).
17
18   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.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.
19
202. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) 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**.
21
223. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In **Cipher.init**, set **opMode** to **CryptoMode.ENCRYPT_MODE** (encryption) and **key** to **SymKey** (the key used for encryption).
23
24   If ECB mode is used, pass **null**.
25
264. Call [Cipher.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-1) to pass in the data to be encrypted (plaintext).
27
28   - If a small amount of data is to be encrypted, you can use **Cipher.doFinal** immediately after **Cipher.init**.
29   - If a large amount of data is to be encrypted, you can call **Cipher.update** multiple times to pass in the data by segment.
30   - You can determine the data size. For example, call **Cipher.update** when the data size is greater than 20 bytes.
31
325. Call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to obtain the encrypted data.
33
34   - If **Cipher.update** has been called, set **data** is set to **null**.
35   - The output of **Cipher.doFinal** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data.
36
37**Decryption**
38
391. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) 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**.
40
412. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In **Cipher.init**, set **opMode** to **CryptoMode.DECRYPT_MODE** (decryption) and **key** to **SymKey** (the key used for decryption). If ECB mode is used, pass **null**.
42
433. Call [Cipher.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-1) to pass in the data to be decrypted (ciphertext).
44
454. Call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to obtain the decrypted data.
46
47## Example
48
49If the cipher mode is ECB, you do not need to set IV parameter for encryption and decryption.
50
51If the CBC, CTR, OFB, or CFB block mode is used, you need to set the IV. For details, see [Setting the IV](#setting-the-iv). Ensure that the related parameters are correctly set when the **Cipher** instance is generated and initialized.
52
53- Example (using asynchronous APIs):
54
55  ```ts
56  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
57  import { buffer } from '@kit.ArkTS';
58
59  // Encrypt the message.
60  async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
61    // If the CBC, CTR, OFB, or CFB mode is used, change the mode to the corresponding mode and add the IV as the encryption and decryption parameter.
62    let cipher = cryptoFramework.createCipher('3DES192|ECB|PKCS7');
63    await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
64    let encryptData = await cipher.doFinal(plainText);
65    return encryptData;
66  }
67  // Decrypt the message.
68  async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
69    // If the CBC, CTR, OFB, or CFB mode is used, change the mode to the corresponding mode and add the IV as the encryption and decryption parameter.
70    let decoder = cryptoFramework.createCipher('3DES192|ECB|PKCS7');
71    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null);
72    let decryptData = await decoder.doFinal(cipherText);
73    return decryptData;
74  }
75  async function genSymKeyByData(symKeyData: Uint8Array) {
76    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
77    let symGenerator = cryptoFramework.createSymKeyGenerator('3DES192');
78    let symKey = await symGenerator.convertKey(symKeyBlob);
79    console.info('convertKey success');
80    return symKey;
81  }
82  async function main() {
83    let keyData = new Uint8Array([238, 249, 61, 55, 128, 220, 183, 224, 139, 253, 248, 239, 239, 41, 71, 25, 235, 206, 230, 162, 249, 27, 234, 114]);
84    let symKey = await genSymKeyByData(keyData);
85    let message = "This is a test";
86    let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
87    let encryptText = await encryptMessagePromise(symKey, plainText);
88    let decryptText = await decryptMessagePromise(symKey, encryptText);
89    if (plainText.data.toString() === decryptText.data.toString()) {
90      console.info('decrypt ok');
91      console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
92    } else {
93      console.error('decrypt failed');
94    }
95  }
96  ```
97
98- Example (using synchronous APIs):
99
100  ```ts
101  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
102  import { buffer } from '@kit.ArkTS';
103
104  // Encrypt the message.
105  function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
106    // If the CBC, CTR, OFB, or CFB mode is used, change the mode to the corresponding mode and add the IV as the encryption and decryption parameter.
107    let cipher = cryptoFramework.createCipher('3DES192|ECB|PKCS7');
108    cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
109    let encryptData = cipher.doFinalSync(plainText);
110    return encryptData;
111  }
112  // Decrypt the message.
113  function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
114    // If the CBC, CTR, OFB, or CFB mode is used, change the mode to the corresponding mode and add the IV as the encryption and decryption parameter.
115    let decoder = cryptoFramework.createCipher('3DES192|ECB|PKCS7');
116    decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null);
117    let decryptData = decoder.doFinalSync(cipherText);
118    return decryptData;
119  }
120  function genSymKeyByData(symKeyData: Uint8Array) {
121    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
122    let symGenerator = cryptoFramework.createSymKeyGenerator('3DES192');
123    let symKey = symGenerator.convertKeySync(symKeyBlob);
124    console.info('convertKeySync success');
125    return symKey;
126  }
127  function main() {
128    let keyData = new Uint8Array([238, 249, 61, 55, 128, 220, 183, 224, 139, 253, 248, 239, 239, 41, 71, 25, 235, 206, 230, 162, 249, 27, 234, 114]);
129    let symKey = genSymKeyByData(keyData);
130    let message = "This is a test";
131    let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
132    let encryptText = encryptMessage(symKey, plainText);
133    let decryptText = decryptMessage(symKey, encryptText);
134    if (plainText.data.toString() === decryptText.data.toString()) {
135      console.info('decrypt ok');
136      console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
137    } else {
138      console.error('decrypt failed');
139    }
140  }
141  ```
142
143### Setting the IV
144
145The following example demonstrates how to set the IV when the CBC mode is used.
146
147If CBC, CTR, OFB, or CFB mode is used, set the IV in the same way. If ECB mode is used, you do not need to set this parameter.
148
149  ```ts
150  function genIvParamsSpec() {
151    let ivBlob = generateRandom (8); // The IV for 3DES CBC, CFB, OFB, or CTR is of 8 bytes.
152    let ivParamsSpec: cryptoFramework.IvParamsSpec = {
153      algName: "IvParamsSpec",
154      iv: ivBlob
155    };
156    return ivParamsSpec;
157  }
158  let iv = genIvParamsSpec();
159  let cipher = cryptoFramework.createCipher('3DES192|CBC|PKCS7');
160  cipher.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
161  // This code snippet only shows the differences between CBC, CTR, OFB, and CFB modes. For details about other processes, see the related development examples.
162  ```
163