1# Generating a CMAC (ArkTS) 2 3<!--Kit: Crypto Architecture Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @zxz--3--> 6<!--Designer: @lanming--> 7<!--Tester: @PAFT--> 8<!--Adviser: @zengyawen--> 9 10The cipher-based message authentication code (CMAC) uses a block cipher (such as AES) and a key to generate an authentication code, which verifies that a message has not been alerted during transmission. 11 12## How to Develop 13 14During the CMAC operation, you can [pass in all the data at a time](#generating-a-cmac-by-passing-in-full-data) or [pass in data by segment](#generating-a-cmac-by-passing-in-data-by-segment). The same data will produce the same result no matter how the data is passed. Use the appropriate method based on the data size. 15 16The following provides examples of CMAC operations with different data passing methods. 17 18### Generating a CMAC by Passing in Full Data 19 201. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac18) with the MAC algorithm set to **CMAC** and symmetric key algorithm set to **AES128** to create a **Mac** instance. 21 222. 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 symmetric key (**SymKey**) using AES256. 23 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 24 253. Call [Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-6) to initialize the **Mac** instance using the shared symmetric key (**SymKey**). 26 274. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-8) to pass in the full data. The amount of data to be passed in by a single **Mac.update()** call is not limited. 28 295. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2) to generate a MAC. 30 316. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 32 33- Example: Pass in the full data to generate a MAC using **await**. 34 35 ```ts 36 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 37 import { buffer } from '@kit.ArkTS'; 38 39 async function genSymKeyByData(symKeyData: Uint8Array) { 40 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 41 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 42 let symKey = await aesGenerator.convertKey(symKeyBlob); 43 console.info('convertKey success'); 44 return symKey; 45 } 46 async function doCmac() { 47 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 48 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 49 let key = await genSymKeyByData(keyData); 50 let spec: cryptoFramework.CmacSpec = { 51 algName: "CMAC", 52 cipherName: "AES128", 53 }; 54 let message = 'cmacTestMessage'; // Message used to generate a CMAC. 55 let mac = cryptoFramework.createMac(spec); 56 await mac.init(key); 57 // For a small amount of data, update it by passing in the full data. The API does not have a limit on the length of input parameters. 58 await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 59 let macResult = await mac.doFinal(); 60 console.info('CMAC result:' + macResult.data); 61 let macLen = mac.getMacLength(); 62 console.info('CMAC len:' + macLen); 63 } 64 ``` 65 66- Example: Pass in the full data to calculate a MAC using synchronous APIs. 67 68 ```ts 69 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 70 import { buffer } from '@kit.ArkTS'; 71 72 function genSymKeyByData(symKeyData: Uint8Array) { 73 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 74 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 75 let symKey = aesGenerator.convertKeySync(symKeyBlob); 76 console.info('[Sync]convertKey success'); 77 return symKey; 78 } 79 function doCmacBySync() { 80 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 81 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 82 let key = genSymKeyByData(keyData); 83 let spec: cryptoFramework.CmacSpec = { 84 algName: "CMAC", 85 cipherName: "AES128", 86 }; 87 let message = 'cmacTestMessage'; // Message used to generate a CMAC. 88 let mac = cryptoFramework.createMac(spec); 89 mac.initSync(key); 90 // For a small amount of data, update it by passing in the full data. The API does not have a limit on the length of input parameters. 91 mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 92 let macResult = mac.doFinalSync(); 93 console.info('[Sync]CMAC result:' + macResult.data); 94 let macLen = mac.getMacLength(); 95 console.info('CMAC len:' + macLen); 96 } 97 ``` 98 99### Generating a CMAC by Passing In Data by Segment 100 1011. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac18) with the MAC algorithm set to **CMAC** and symmetric key algorithm set to **AES256** to create a **Mac** instance. 102 1032. 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 symmetric key (**SymKey**) using AES256. 104 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 105 1063. Call [Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-7) to initialize the **Mac** instance using the shared symmetric key (**SymKey**). 107 1084. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9) multiple times to pass in 20 bytes each time. 109 1105. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3) to generate a MAC. 111 1126. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 113 114- Example: Pass in data by segment to generate a MAC using **await**. 115 116 ```ts 117 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 118 import { buffer } from '@kit.ArkTS'; 119 120 async function genSymKeyByData(symKeyData: Uint8Array) { 121 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 122 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 123 let symKey = await aesGenerator.convertKey(symKeyBlob); 124 console.info('convertKey success'); 125 return symKey; 126 } 127 async function doLoopCmac() { 128 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 129 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 130 let key = await genSymKeyByData(keyData); 131 let spec: cryptoFramework.CmacSpec = { 132 algName: "CMAC", 133 cipherName: "AES128", 134 }; 135 let mac = cryptoFramework.createMac(spec); 136 // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 137 let messageText = "aaaaa......bbbbb......ccccc......ddddd......eee"; 138 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 139 let updateLength = 20; // Pass in 20 bytes each time. You can set this parameter as required. 140 await mac.init(key); 141 for (let i = 0; i < messageData.length; i += updateLength) { 142 let updateMessage = messageData.subarray(i, i + updateLength); 143 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 144 await mac.update(updateMessageBlob); 145 } 146 let macOutput = await mac.doFinal(); 147 console.info("CMAC result: " + macOutput.data); 148 let macLen = mac.getMacLength(); 149 console.info('CMAC len:' + macLen); 150 } 151 ``` 152 153- Example: Pass in data by segment to generate a MAC using synchronous APIs. 154 155 ```ts 156 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 157 import { buffer } from '@kit.ArkTS'; 158 159 function genSymKeyByData(symKeyData: Uint8Array) { 160 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 161 let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128'); 162 let symKey = aesGenerator.convertKeySync(symKeyBlob); 163 console.info('[Sync]convertKey success'); 164 return symKey; 165 } 166 function doLoopCmacBySync() { 167 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 168 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 169 let key = genSymKeyByData(keyData); 170 let spec: cryptoFramework.CmacSpec = { 171 algName: "CMAC", 172 cipherName: "AES128", 173 }; 174 let mac = cryptoFramework.createMac(spec); 175 // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 176 let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; 177 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 178 let updateLength = 20; // Pass in 20 bytes each time. You can set this parameter as required. 179 mac.initSync(key); 180 for (let i = 0; i < messageData.length; i += updateLength) { 181 let updateMessage = messageData.subarray(i, i + updateLength); 182 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 183 mac.updateSync(updateMessageBlob); 184 } 185 let macOutput = mac.doFinalSync(); 186 console.info("[Sync]CMAC result: " + macOutput.data); 187 let macLen = mac.getMacLength(); 188 console.info('CMAC len:' + macLen); 189 } 190 ``` 191