1# Encryption and Decryption with an AES Symmetric Key (CCM 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, see [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|CCM'** to create a **Cipher** instance for encryption. The key type is AES128, and the block cipher mode is CCM. 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**, and **params** to **CcmParamsSpec** corresponding to the CCM mode. 21 224. Call [Cipher.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-1) to pass in the data to be encrypted (plaintext). 23 24 Currently, there is no length limit for a single update. You can call **Cipher.update** based on the data volume. 25 26 > **NOTE**<br> 27 > The CCM mode does not support segment-based encryption and decryption. 28 295. Call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to obtain the encrypted data. 30 - If data has been passed in by **Cipher.update**, pass in **null** in this step. 31 - The output of **Cipher.doFinal** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data. 32 336. Obtain [CcmParamsSpec.authTag](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#ccmparamsspec) as the authentication information for decryption. 34 35 In CCM mode, the algorithm library supports only 12-byte **authTag**, which is used for initialization authentication during decryption. In the following example, **authTag** is of 12 bytes. 36 37**Decryption** 38 391. Call [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'AES128|CCM'** to create a **Cipher** instance for decryption. The key type is AES128, and the block cipher mode is CCM. 40 412. 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**, and **params** to **CcmParamsSpec** corresponding to the CCM mode. 42 433. Call [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to obtain the decrypted data. 44 45- Example (using asynchronous APIs): 46 47 ```ts 48 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 49 import { buffer } from '@kit.ArkTS'; 50 51 function genCcmParamsSpec() { 52 let rand: cryptoFramework.Random = cryptoFramework.createRandom(); 53 let ivBlob: cryptoFramework.DataBlob = rand.generateRandomSync(7); 54 let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8); 55 let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes 56 let dataTag = new Uint8Array(arr); 57 let tagBlob: cryptoFramework.DataBlob = { 58 data: dataTag 59 }; 60 // Obtain the CCM authTag from the Cipher.doFinal result in encryption and fill it in the params parameter of Cipher.init in decryption. 61 let ccmParamsSpec: cryptoFramework.CcmParamsSpec = { 62 iv: ivBlob, 63 aad: aadBlob, 64 authTag: tagBlob, 65 algName: "CcmParamsSpec" 66 }; 67 return ccmParamsSpec; 68 } 69 let ccmParams = genCcmParamsSpec(); 70 71 // Encrypt the message. 72 async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { 73 let cipher = cryptoFramework.createCipher('AES128|CCM'); 74 await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ccmParams); 75 let encryptUpdate = await cipher.update(plainText); 76 // In CCM mode, pass in null in Cipher.doFinal in encryption. Obtain the tag data and fill it in the ccmParams object. 77 ccmParams.authTag = await cipher.doFinal(null); 78 return encryptUpdate; 79 } 80 // Decrypt the message. 81 async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { 82 let decoder = cryptoFramework.createCipher('AES128|CCM'); 83 await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ccmParams); 84 let decryptUpdate = await decoder.doFinal(cipherText); 85 return decryptUpdate; 86 } 87 async function genSymKeyByData(symKeyData: Uint8Array) { 88 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 89 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 90 let symKey = await aesGenerator.convertKey(symKeyBlob); 91 console.info('convertKey success'); 92 return symKey; 93 } 94 async function main() { 95 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); 96 let symKey = await genSymKeyByData(keyData); 97 let message = "This is a test"; 98 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 99 let encryptText = await encryptMessagePromise(symKey, plainText); 100 let decryptText = await decryptMessagePromise(symKey, encryptText); 101 if (plainText.data.toString() === decryptText.data.toString()) { 102 console.info('decrypt ok'); 103 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 104 } else { 105 console.error('decrypt failed'); 106 } 107 } 108 ``` 109 110- Example (using synchronous APIs): 111 112 ```ts 113 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 114 import { buffer } from '@kit.ArkTS'; 115 116 117 function genCcmParamsSpec() { 118 let rand: cryptoFramework.Random = cryptoFramework.createRandom(); 119 let ivBlob: cryptoFramework.DataBlob = rand.generateRandomSync(7); 120 let aadBlob: cryptoFramework.DataBlob = rand.generateRandomSync(8); 121 let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes 122 let dataTag = new Uint8Array(arr); 123 let tagBlob: cryptoFramework.DataBlob = { 124 data: dataTag 125 }; 126 // Obtain the CCM authTag from the Cipher.doFinal result in encryption and fill it in the params parameter of Cipher.init in decryption. 127 let ccmParamsSpec: cryptoFramework.CcmParamsSpec = { 128 iv: ivBlob, 129 aad: aadBlob, 130 authTag: tagBlob, 131 algName: "CcmParamsSpec" 132 }; 133 return ccmParamsSpec; 134 } 135 136 let ccmParams = genCcmParamsSpec(); 137 138 // Encrypt the message. 139 function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) { 140 let cipher = cryptoFramework.createCipher('AES128|CCM'); 141 cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ccmParams); 142 let encryptUpdate = cipher.updateSync(plainText); 143 // In CCM mode, pass in null in Cipher.doFinal in encryption. Obtain the tag data and fill it in the ccmParams object. 144 ccmParams.authTag = cipher.doFinalSync(null); 145 return encryptUpdate; 146 } 147 // Decrypt the message. 148 function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) { 149 let decoder = cryptoFramework.createCipher('AES128|CCM'); 150 decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ccmParams); 151 let decryptUpdate = decoder.doFinalSync(cipherText); 152 return decryptUpdate; 153 } 154 function genSymKeyByData(symKeyData: Uint8Array) { 155 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 156 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 157 let symKey = aesGenerator.convertKeySync(symKeyBlob); 158 console.info('convertKeySync success'); 159 return symKey; 160 } 161 function main() { 162 let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]); 163 let symKey = genSymKeyByData(keyData); 164 let message = "This is a test"; 165 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 166 let encryptText = encryptMessage(symKey, plainText); 167 let decryptText = decryptMessage(symKey, encryptText); 168 if (plainText.data.toString() === decryptText.data.toString()) { 169 console.info('decrypt ok'); 170 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 171 } else { 172 console.error('decrypt failed'); 173 } 174 } 175 ``` 176