• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Generating an HMAC (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 hash-based message authentication code (HMAC) algorithm employs a designated digest algorithm and takes a shared key and message as inputs to generate a fixed-length message authentication code (MAC) to check the integrity of packets. The HMAC adds key input on the basis of the message digest algorithm to ensure information correctness.
11
12## How to Develop
13
14During 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.
15
16The following provides examples of HMAC operations with different data passing methods.
17
18### Generating an HMAC by Passing In Full Data
19
201. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm **SHA256** 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 HMAC.
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 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('HMAC');
42    let symKey = await aesGenerator.convertKey(symKeyBlob);
43    console.info('convertKey success');
44    return symKey;
45  }
46  async function doHmac() {
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 macAlgName = 'SHA256'; // MD algorithm.
51    let message = 'hmacTestMessage'; // Message to be HMACed.
52    let mac = cryptoFramework.createMac(macAlgName);
53    await mac.init(key);
54    // For a small amount of data, you can pass in full data in a single update. The API does not limit the length of the input parameter.
55    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
56    let macResult = await mac.doFinal();
57    console.info('HMAC result:' + macResult.data);
58    let macLen = mac.getMacLength();
59    console.info('HMAC len:' + macLen);
60  }
61  ```
62
63- Example: Pass in the full data to generate a MAC using synchronous APIs.
64
65  ```ts
66  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
67  import { buffer } from '@kit.ArkTS';
68
69  function genSymKeyByData(symKeyData: Uint8Array) {
70    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
71    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
72    let symKey =  aesGenerator.convertKeySync(symKeyBlob);
73    console.info('[Sync]convertKey success');
74    return symKey;
75  }
76  function doHmacBySync() {
77    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
78    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
79    let key = genSymKeyByData(keyData);
80    let macAlgName = 'SHA256'; // MD algorithm.
81    let message = 'hmacTestMessage'; // Message to be HMACed.
82    let mac = cryptoFramework.createMac(macAlgName);
83    mac.initSync(key);
84    // For a small amount of data, you can pass in full data in a single update. The API does not limit the length of the input parameter.
85    mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
86    let macResult = mac.doFinalSync();
87    console.info('[Sync]HMAC result:' + macResult.data);
88    let macLen = mac.getMacLength();
89    console.info('HMAC len:' + macLen);
90  }
91  ```
92
93### Generating an HMAC by Passing In Data by Segment
94
951. Call [cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac) with the MD algorithm **SHA256** to create a **Mac** instance.
96
972. 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.
98   For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md).
99
1003. 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**).
101
1024. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9) multiple times to pass in 20 bytes each time.
103
1045. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3) to generate a MAC.
105
1066. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes.
107
108- Example: Pass in data by segment to generate a MAC using **await**.
109
110  ```ts
111  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
112  import { buffer } from '@kit.ArkTS';
113
114  async function genSymKeyByData(symKeyData: Uint8Array) {
115    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
116    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
117    let symKey = await aesGenerator.convertKey(symKeyBlob);
118    console.info('convertKey success');
119    return symKey;
120  }
121  async function doLoopHmac() {
122    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
123    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
124    let key = await genSymKeyByData(keyData);
125    let macAlgName = "SHA256"; // MD algorithm.
126    let mac = cryptoFramework.createMac(macAlgName);
127    // The message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes.
128    let messageText = "aaaaa......bbbbb......ccccc......ddddd......eee";
129    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
130    let updateLength = 20; // Update data in segments of 20 bytes.
131    await mac.init(key);
132    for (let i = 0; i < messageData.length; i += updateLength) {
133      let updateMessage = messageData.subarray(i, i + updateLength);
134      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
135      await mac.update(updateMessageBlob);
136    }
137    let macOutput = await mac.doFinal();
138    console.info("HMAC result: " + macOutput.data);
139    let macLen = mac.getMacLength();
140    console.info('HMAC len:' + macLen);
141  }
142  ```
143
144- Pass in data by segment to generate a MAC using synchronous APIs.
145
146  ```ts
147  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
148  import { buffer } from '@kit.ArkTS';
149
150  function genSymKeyByData(symKeyData: Uint8Array) {
151    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
152    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
153    let symKey = aesGenerator.convertKeySync(symKeyBlob);
154    console.info('[Sync]convertKey success');
155    return symKey;
156  }
157  function doLoopHmacBySync() {
158    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
159    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
160    let key = genSymKeyByData(keyData);
161    let macAlgName = "SHA256"; // MD algorithm.
162    let mac = cryptoFramework.createMac(macAlgName);
163    // The message is of 43 bytes, decoded in UTF-8 format.
164    let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee";
165    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
166    let updateLength = 20; // Pass in 20 bytes each time. You can set this parameter as required.
167    mac.initSync(key);
168    for (let i = 0; i < messageData.length; i += updateLength) {
169      let updateMessage = messageData.subarray(i, i + updateLength);
170      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
171      mac.updateSync(updateMessageBlob);
172    }
173    let macOutput = mac.doFinalSync();
174    console.info("[Sync]HMAC result: " + macOutput.data);
175    let macLen = mac.getMacLength();
176    console.info('HMAC len:' + macLen);
177  }
178  ```
179
180
181### Generating an HMAC by Passing In HmacSpec as a Parameter
1821. 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.
183
1842. 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.
185   For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md).
186
1873. 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**).
188
1894. 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.
190
1915. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2) to generate a MAC.
192
1936. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes.
194
195- Example: Pass in the full data to generate a MAC using **await**.
196
197  ```ts
198  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
199  import { buffer } from '@kit.ArkTS';
200
201  async function genSymKeyByData(symKeyData: Uint8Array) {
202    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
203    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
204    let symKey = await aesGenerator.convertKey(symKeyBlob);
205    console.info('convertKey success');
206    return symKey;
207  }
208  async function doHmac() {
209    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
210    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
211    let key = await genSymKeyByData(keyData);
212    let spec: cryptoFramework.HmacSpec = {
213        algName: "HMAC",
214        mdName: "SHA256",
215    };
216    let message = 'hmacTestMessage'; // Message to be HMACed.
217    let mac = cryptoFramework.createMac(spec);
218    await mac.init(key);
219    // For a small amount of data, you can pass in full data in a single update. The API does not limit the length of the input parameter.
220    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
221    let macResult = await mac.doFinal();
222    console.info('HMAC result:' + macResult.data);
223    let macLen = mac.getMacLength();
224    console.info('HMAC len:' + macLen);
225  }
226  ```
227