1# Encryption and Decryption with an AES Symmetric Key (CBC Mode) (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 [Symmetric Key Encryption and Decryption Algorithm Specifications: AES](crypto-sym-encrypt-decrypt-spec.md#aes). 11 12**Encryption** 13 141. Call [cryptoFramework.createSymKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesymkeygenerator) and [SymKeyGenerator.generateSymKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatesymkey-1) to generate a 128-bit AES symmetric key (**SymKey**). 15 16 In 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.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. 17 182. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'AES128|CBC|PKCS7'** to create a **Cipher** instance for encryption. The key type is **AES128**, block cipher mode is **CBC**, and the padding mode is **PKCS7**. 19 203. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In the **Cipher.init** API, set **opMode** to **CryptoMode.ENCRYPT_MODE** (encryption), **key** to **SymKey** (the key for encryption), and **params** to **IvParamsSpec** corresponding to the CBC mode. 21 224. To encrypt a small amount of data, simply call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1). 23 24**Decryption** 25 261. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'AES128|CBC|PKCS7'** to create a **Cipher** instance for decryption. The key type is **AES128**, block cipher mode is **CBC**, and the padding mode is **PKCS7**. 27 282. Call [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In the **Cipher.init** API, set **opMode** to **CryptoMode.DECRYPT_MODE** (decryption), **key** to **SymKey** (the key for decryption), and **params** to **IvParamsSpec** corresponding to the CBC mode. 29 303. To decrypt a small amount of data, simply call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1). 31 32- Example (using asynchronous APIs): 33 34 ```ts 35 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 36 import { buffer } from '@kit.ArkTS'; 37 38 function generateRandom(len: number) { 39 let rand = cryptoFramework.createRandom(); 40 let generateRandSync = rand.generateRandomSync(len); 41 return generateRandSync; 42 } 43 44 function genIvParamsSpec() { 45 let ivBlob = generateRandom(16); 46 let ivParamsSpec: cryptoFramework.IvParamsSpec = { 47 algName: "IvParamsSpec", 48 iv: ivBlob 49 }; 50 return ivParamsSpec; 51 } 52 let iv = genIvParamsSpec(); 53 // Encrypt the message. 54 async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { 55 let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7'); 56 await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv); 57 let cipherData = await cipher.doFinal(plainText); 58 return cipherData; 59 } 60 // Decrypt the message. 61 async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { 62 let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7'); 63 await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv); 64 let decryptData = await decoder.doFinal(cipherText); 65 return decryptData; 66 } 67 68 async function genSymKeyByData(symKeyData: Uint8Array) { 69 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 70 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 71 let symKey = await aesGenerator.convertKey(symKeyBlob); 72 console.info('convertKey success'); 73 return symKey; 74 } 75 76 async function aesCBC() { 77 try { 78 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); 79 let symKey = await genSymKeyByData(keyData); 80 let message = "This is a test"; 81 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 82 let encryptText = await encryptMessagePromise(symKey, plainText); 83 let decryptText = await decryptMessagePromise(symKey, encryptText); 84 if (plainText.data.toString() === decryptText.data.toString()) { 85 console.info('decrypt ok'); 86 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 87 } else { 88 console.error('decrypt failed'); 89 } 90 } catch (error) { 91 console.error(`AES CBC "${error}", error code: ${error.code}`); 92 } 93 } 94 ``` 95 96- Example (using synchronous APIs): 97 98 ```ts 99 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 100 import { buffer } from '@kit.ArkTS'; 101 102 function generateRandom(len: number) { 103 let rand = cryptoFramework.createRandom(); 104 let generateRandSync = rand.generateRandomSync(len); 105 return generateRandSync; 106 } 107 108 function genIvParamsSpec() { 109 let ivBlob = generateRandom(16); 110 let ivParamsSpec: cryptoFramework.IvParamsSpec = { 111 algName: "IvParamsSpec", 112 iv: ivBlob 113 }; 114 return ivParamsSpec; 115 } 116 let iv = genIvParamsSpec(); 117 // Encrypt the message. 118 function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { 119 let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7'); 120 cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv); 121 let cipherData = cipher.doFinalSync(plainText); 122 return cipherData; 123 } 124 // Decrypt the message. 125 function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { 126 let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7'); 127 decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv); 128 let decryptData = decoder.doFinalSync(cipherText); 129 return decryptData; 130 } 131 132 function genSymKeyByData(symKeyData: Uint8Array) { 133 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 134 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 135 let symKey = aesGenerator.convertKeySync(symKeyBlob); 136 console.info('convertKeySync success'); 137 return symKey; 138 } 139 140 function main() { 141 try { 142 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); 143 let symKey = genSymKeyByData(keyData); 144 let message = "This is a test"; 145 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 146 let encryptText = encryptMessage(symKey, plainText); 147 let decryptText = decryptMessage(symKey, encryptText); 148 if (plainText.data.toString() === decryptText.data.toString()) { 149 console.info('decrypt ok'); 150 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 151 } else { 152 console.error('decrypt failed'); 153 } 154 } catch (error) { 155 console.error(`AES CBC "${error}", error code: ${error.code}`); 156 } 157 } 158 ``` 159