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