1# Generating an HMAC 2 3 4A message authentication code (MAC) is used to check the authenticity and integrity of a message transmitted between two parties that share a secret key. A Hash-based Message Authentication Code (HMAC) is a type of MAC involving a hash function and a secret key. The generated MAC has a fixed length. 5 6 7 8## How to Develop 9 10During the HMAC operation, you can [pass in all the data at a time](#generating-an-hmac-by-passing-in-full-data) or [pass in data by segment](#generating-an-hmac-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. 11 12The following provides examples of HMAC operations with different data passing methods. 13 14 15### Generating an HMAC by Passing In Full Data 16 171. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm **SHA256** to create a **Mac** instance. 18 192. 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 HMAC. 20 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 21 223. 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**). 23 244. 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. 25 265. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2) to generate a MAC. 27 286. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 29 30- Example: Pass in the full data to generate a MAC using **await**. 31 32 ```ts 33 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 34 import { buffer } from '@kit.ArkTS'; 35 36 async function genSymKeyByData(symKeyData: Uint8Array) { 37 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 38 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 39 let symKey = await aesGenerator.convertKey(symKeyBlob); 40 console.info('convertKey success'); 41 return symKey; 42 } 43 async function doHmac() { 44 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 45 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 46 let key = await genSymKeyByData(keyData); 47 let macAlgName = 'SHA256'; // MD algorithm. 48 let message = 'hmacTestMessage'; // Message to be HMACed. 49 let mac = cryptoFramework.createMac(macAlgName); 50 await mac.init(key); 51 // 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. 52 await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 53 let macResult = await mac.doFinal(); 54 console.info('HMAC result:' + macResult.data); 55 let macLen = mac.getMacLength(); 56 console.info('HMAC len:' + macLen); 57 } 58 ``` 59 60- Example: Pass in the full data to generate a MAC using synchronous APIs. 61 62 ```ts 63 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 64 import { buffer } from '@kit.ArkTS'; 65 66 function genSymKeyByData(symKeyData: Uint8Array) { 67 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 68 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 69 let symKey = aesGenerator.convertKeySync(symKeyBlob); 70 console.info('[Sync]convertKey success'); 71 return symKey; 72 } 73 function doHmacBySync() { 74 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 75 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 76 let key = genSymKeyByData(keyData); 77 let macAlgName = 'SHA256'; // MD algorithm. 78 let message = 'hmacTestMessage'; // Message to be HMACed. 79 let mac = cryptoFramework.createMac(macAlgName); 80 mac.initSync(key); 81 // 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. 82 mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 83 let macResult = mac.doFinalSync(); 84 console.info('[Sync]HMAC result:' + macResult.data); 85 let macLen = mac.getMacLength(); 86 console.info('HMAC len:' + macLen); 87 } 88 ``` 89 90### Generating an HMAC by Passing In Data by Segment 91 921. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm **SHA256** to create a **Mac** instance. 93 942. 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 HMAC. 95 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 96 973. 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**). 98 994. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9) multiple times to pass in 20 bytes each time. 100 1015. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3) to generate a MAC. 102 1036. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 104 105- Example: Pass in data by segment to generate a MAC using **await**. 106 107 ```ts 108 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 109 import { buffer } from '@kit.ArkTS'; 110 111 async function genSymKeyByData(symKeyData: Uint8Array) { 112 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 113 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 114 let symKey = await aesGenerator.convertKey(symKeyBlob); 115 console.info('convertKey success'); 116 return symKey; 117 } 118 async function doLoopHmac() { 119 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 120 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 121 let key = await genSymKeyByData(keyData); 122 let macAlgName = "SHA256"; // MD algorithm. 123 let mac = cryptoFramework.createMac(macAlgName); 124 // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 125 let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; 126 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 127 let updateLength = 20; // Set the data length to be passed in each time to 20 bytes. You can set this parameter as required. 128 await mac.init(key); 129 for (let i = 0; i < messageData.length; i += updateLength) { 130 let updateMessage = messageData.subarray(i, i + updateLength); 131 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 132 await mac.update(updateMessageBlob); 133 } 134 let macOutput = await mac.doFinal(); 135 console.info("HMAC result: " + macOutput.data); 136 let macLen = mac.getMacLength(); 137 console.info('HMAC len:' + macLen); 138 } 139 ``` 140 141- Example: Pass in data by segment to generate a MAC using synchronous APIs. 142 143 ```ts 144 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 145 import { buffer } from '@kit.ArkTS'; 146 147 function genSymKeyByData(symKeyData: Uint8Array) { 148 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 149 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 150 let symKey = aesGenerator.convertKeySync(symKeyBlob); 151 console.info('[Sync]convertKey success'); 152 return symKey; 153 } 154 function doLoopHmacBySync() { 155 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 156 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 157 let key = genSymKeyByData(keyData); 158 let macAlgName = "SHA256"; // MD algorithm. 159 let mac = cryptoFramework.createMac(macAlgName); 160 // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 161 let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; 162 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 163 let updateLength = 20; // Set the data length to be passed in each time to 20 bytes. You can set this parameter as required. 164 mac.initSync(key); 165 for (let i = 0; i < messageData.length; i += updateLength) { 166 let updateMessage = messageData.subarray(i, i + updateLength); 167 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 168 mac.updateSync(updateMessageBlob); 169 } 170 let macOutput = mac.doFinalSync(); 171 console.info("[Sync]HMAC result: " + macOutput.data); 172 let macLen = mac.getMacLength(); 173 console.info('HMAC len:' + macLen); 174 } 175 ``` 176 177 178### Generating an HMAC by Passing In HmacSpec as a Parameter 1791. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MAC algorithm set to **HMAC** and MD algorithm set to **SHA256** to create a **MAc** instance. 180 1812. 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 HMAC. 182 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 183 1843. 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**). 185 1864. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-8) to pass in the data. The amount of data to be passed in by a single **Mac.update()** call is not limited. 187 1885. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2) to generate a MAC. 189 1906. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 191 192- Example: Pass in the full data to generate a MAC using **await**. 193 194 ```ts 195 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 196 import { buffer } from '@kit.ArkTS'; 197 198 async function genSymKeyByData(symKeyData: Uint8Array) { 199 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 200 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 201 let symKey = await aesGenerator.convertKey(symKeyBlob); 202 console.info('convertKey success'); 203 return symKey; 204 } 205 async function doHmac() { 206 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 207 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 208 let key = await genSymKeyByData(keyData); 209 let spec: cryptoFramework.HmacSpec = { 210 algName: "HMAC", 211 mdName: "SHA256", 212 }; 213 let message = 'hmacTestMessage'; // Message to be HMACed. 214 let mac = cryptoFramework.createMac(spec); 215 await mac.init(key); 216 // 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. 217 await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 218 let macResult = await mac.doFinal(); 219 console.info('HMAC result:' + macResult.data); 220 let macLen = mac.getMacLength(); 221 console.info('HMAC len:' + macLen); 222 } 223 ``` 224