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