1# MAC Operations 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. 5 6 7A Hash-based Message Authentication Code (HMAC) is a type of MAC involving a hash function and a secret key. 8 9 10The specified message digest (MD) algorithm is used to generate a MAC based on the shared secret key and the message to be exchanged. The MAC is used to check the integrity of message. HMAC introduces the shared secret key, which ensures data authenticity. The generated MAC has a fixed length. 11 12 13## Supported Algorithms and Specifications 14 15The **Supported Type** column in the following table lists the algorithm to be used when a **Mac** instance is created. 16 17| MD Algorithm| Supported Type| API Version| 18| -------- | -------- | -------- | 19| HASH | SHA1 | 9+ | 20| HASH | SHA224 | 9+ | 21| HASH | SHA256 | 9+ | 22| HASH | SHA384 | 9+ | 23| HASH | SHA512 | 9+ | 24| HASH | SM3 | 10+ | 25| HASH | MD5 | 12+ | 26 27## How to Develop 28 29During the HMAC operation, you can use **update()** to pass in all the data at a time or pass 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. 30 31The following provides examples of HMAC operations with different data passing methods. 32 33 34### HMAC (Passing In Full Data) 35 361. Use [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm SHA256 to create a **Mac** instance. 37 382. Use [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**) for HMAC. 39 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 40 413. Use [Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-6) to initialize the **Mac** instance using the shared symmetric key (**SymKey**). 42 434. Use [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-8) to pass in the full data. The data to be passed in by a single **update()** operation is not size bound. 44 455. Use [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2) to generate a MAC. 46 476. Use [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 48 49- Example: Pass in the full data to calculate a MAC using **await**. 50 51 ```ts 52 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 53 import { buffer } from '@kit.ArkTS'; 54 55 async function genSymKeyByData(symKeyData: Uint8Array) { 56 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 57 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 58 let symKey = await aesGenerator.convertKey(symKeyBlob); 59 console.info('convertKey success'); 60 return symKey; 61 } 62 async function doHmac() { 63 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 64 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 65 let key = await genSymKeyByData(keyData); 66 let macAlgName = 'SHA256'; // MD algorithm. 67 let message = 'hmacTestMessgae'; // Message to be HMACed. 68 let mac = cryptoFramework.createMac(macAlgName); 69 await mac.init(key); 70 // If the data to be processed is short, use update() to pass in the full data at a time. The data to be passed in by a single **update()** operation is not size bound. 71 await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 72 let macResult = await mac.doFinal(); 73 console.info('HMAC result:' + macResult.data); 74 let macLen = mac.getMacLength(); 75 console.info('HMAC len:' + macLen); 76 } 77 ``` 78 79- Example: Pass in the full data to calculate a MAC using synchronous APIs. 80 81 ```ts 82 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 83 import { buffer } from '@kit.ArkTS'; 84 85 function genSymKeyByData(symKeyData: Uint8Array) { 86 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 87 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 88 let symKey = aesGenerator.convertKeySync(symKeyBlob); 89 console.info('[Sync]convertKey success'); 90 return symKey; 91 } 92 function doHmacBySync() { 93 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 94 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 95 let key = genSymKeyByData(keyData); 96 let macAlgName = 'SHA256'; // MD algorithm. 97 let message = 'hmacTestMessgae'; // Message to be HMACed. 98 let mac = cryptoFramework.createMac(macAlgName); 99 mac.initSync(key); 100 // If the data to be processed is short, use update() to pass in the full data at a time. The data to be passed in by a single **update()** operation is not size bound. 101 mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }); 102 let macResult = mac.doFinalSync(); 103 console.info('[Sync]HMAC result:' + macResult.data); 104 let macLen = mac.getMacLength(); 105 console.info('HMAC len:' + macLen); 106 } 107 ``` 108 109### HMAC (Passing In Data by Segment) 110 1111. Use [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm SHA256 to create a **Mac** instance. 112 1132. Use [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**) for HMAC. 114 For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md). 115 1163. Use [Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-7) to initialize the **Mac** instance using the shared symmetric key (**SymKey**). 117 1184. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9) multiple times to pass in 20 bytes each time. 119 1205. Use [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3) to generate a MAC. 121 1226. Use [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes. 123 124- Example: Pass in data by segment to calculate a MAC using **await**. 125 126 ```ts 127 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 128 import { buffer } from '@kit.ArkTS'; 129 130 async function genSymKeyByData(symKeyData: Uint8Array) { 131 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 132 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 133 let symKey = await aesGenerator.convertKey(symKeyBlob); 134 console.info('convertKey success'); 135 return symKey; 136 } 137 async function doLoopHmac() { 138 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 139 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 140 let key = await genSymKeyByData(keyData); 141 let macAlgName = "SHA256"; // MD algorithm. 142 let mac = cryptoFramework.createMac(macAlgName); 143 // Assume that the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 144 let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; 145 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 146 let updateLength = 20; // In this example, pass in 20 bytes each time. 147 await mac.init(key); 148 for (let i = 0; i < messageData.length; i += updateLength) { 149 let updateMessage = messageData.subarray(i, i + updateLength); 150 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 151 await mac.update(updateMessageBlob); 152 } 153 let macOutput = await mac.doFinal(); 154 console.info("HMAC result: " + macOutput.data); 155 let macLen = mac.getMacLength(); 156 console.info('HMAC len:' + macLen); 157 } 158 ``` 159 160- Example: Pass in data by segment to calculate a MAC using synchronous APIs. 161 162 ```ts 163 import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 164 import { buffer } from '@kit.ArkTS'; 165 166 function genSymKeyByData(symKeyData: Uint8Array) { 167 let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData }; 168 let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC'); 169 let symKey = aesGenerator.convertKeySync(symKeyBlob); 170 console.info('[Sync]convertKey success'); 171 return symKey; 172 } 173 function doLoopHmacBySync() { 174 // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes). 175 let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer); 176 let key = genSymKeyByData(keyData); 177 let macAlgName = "SHA256"; // MD algorithm. 178 let mac = cryptoFramework.createMac(macAlgName); 179 // Assume that the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes. 180 let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; 181 let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer); 182 let updateLength = 20; // In this example, pass in 20 bytes each time. 183 mac.initSync(key); 184 for (let i = 0; i < messageData.length; i += updateLength) { 185 let updateMessage = messageData.subarray(i, i + updateLength); 186 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 187 mac.updateSync(updateMessageBlob); 188 } 189 let macOutput = mac.doFinalSync(); 190 console.info("[Sync]HMAC result: " + macOutput.data); 191 let macLen = mac.getMacLength(); 192 console.info('HMAC len:' + macLen); 193 } 194 ``` 195