• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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