• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Generating a CMAC (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 cipher-based message authentication code (CMAC) uses a block cipher (such as AES) and a key to generate an authentication code, which verifies that a message has not been alerted during transmission.
11
12## How to Develop
13
14During 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.
15
16The following provides examples of CMAC operations with different data passing methods.
17
18### Generating a CMAC by Passing in Full Data
19
201. 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 **AES128** 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 AES256.
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 full 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('AES128');
42    let symKey = await aesGenerator.convertKey(symKeyBlob);
43    console.info('convertKey success');
44    return symKey;
45  }
46  async function doCmac() {
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 spec: cryptoFramework.CmacSpec = {
51        algName: "CMAC",
52        cipherName: "AES128",
53    };
54    let message = 'cmacTestMessage'; // Message used to generate a CMAC.
55    let mac = cryptoFramework.createMac(spec);
56    await mac.init(key);
57    // For a small amount of data, update it by passing in the full data. The API does not have a limit on the length of input parameters.
58    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
59    let macResult = await mac.doFinal();
60    console.info('CMAC result:' + macResult.data);
61    let macLen = mac.getMacLength();
62    console.info('CMAC len:' + macLen);
63  }
64  ```
65
66- Example: Pass in the full data to calculate a MAC using synchronous APIs.
67
68  ```ts
69  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
70  import { buffer } from '@kit.ArkTS';
71
72  function genSymKeyByData(symKeyData: Uint8Array) {
73    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
74    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
75    let symKey =  aesGenerator.convertKeySync(symKeyBlob);
76    console.info('[Sync]convertKey success');
77    return symKey;
78  }
79  function doCmacBySync() {
80    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
81    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
82    let key = genSymKeyByData(keyData);
83    let spec: cryptoFramework.CmacSpec = {
84        algName: "CMAC",
85        cipherName: "AES128",
86    };
87    let message = 'cmacTestMessage'; // Message used to generate a CMAC.
88    let mac = cryptoFramework.createMac(spec);
89    mac.initSync(key);
90    // For a small amount of data, update it by passing in the full data. The API does not have a limit on the length of input parameters.
91    mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
92    let macResult = mac.doFinalSync();
93    console.info('[Sync]CMAC result:' + macResult.data);
94    let macLen = mac.getMacLength();
95    console.info('CMAC len:' + macLen);
96  }
97  ```
98
99### Generating a CMAC by Passing In Data by Segment
100
1011. 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.
102
1032. 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.
104   For details, see [Converting Binary Data into a Symmetric Key](crypto-convert-binary-data-to-sym-key.md).
105
1063. 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**).
107
1084. Call [Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9) multiple times to pass in 20 bytes each time.
109
1105. Call [Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3) to generate a MAC.
111
1126. Call [Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength) to obtain the length of the MAC, in bytes.
113
114- Example: Pass in data by segment to generate a MAC using **await**.
115
116  ```ts
117  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
118  import { buffer } from '@kit.ArkTS';
119
120  async function genSymKeyByData(symKeyData: Uint8Array) {
121    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
122    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
123    let symKey = await aesGenerator.convertKey(symKeyBlob);
124    console.info('convertKey success');
125    return symKey;
126  }
127  async function doLoopCmac() {
128    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
129    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
130    let key = await genSymKeyByData(keyData);
131    let spec: cryptoFramework.CmacSpec = {
132        algName: "CMAC",
133        cipherName: "AES128",
134    };
135    let mac = cryptoFramework.createMac(spec);
136    // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes.
137    let messageText = "aaaaa......bbbbb......ccccc......ddddd......eee";
138    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
139    let updateLength = 20; // Pass in 20 bytes each time. You can set this parameter as required.
140    await mac.init(key);
141    for (let i = 0; i < messageData.length; i += updateLength) {
142      let updateMessage = messageData.subarray(i, i + updateLength);
143      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
144      await mac.update(updateMessageBlob);
145    }
146    let macOutput = await mac.doFinal();
147    console.info("CMAC result: " + macOutput.data);
148    let macLen = mac.getMacLength();
149    console.info('CMAC len:' + macLen);
150  }
151  ```
152
153- Example: Pass in data by segment to generate a MAC using synchronous APIs.
154
155  ```ts
156  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
157  import { buffer } from '@kit.ArkTS';
158
159  function genSymKeyByData(symKeyData: Uint8Array) {
160    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
161    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
162    let symKey = aesGenerator.convertKeySync(symKeyBlob);
163    console.info('[Sync]convertKey success');
164    return symKey;
165  }
166  function doLoopCmacBySync() {
167    // Convert the string into a Uint8Array in UTF-8 format and use it as the private key, which is 128 bits (16 bytes).
168    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
169    let key = genSymKeyByData(keyData);
170    let spec: cryptoFramework.CmacSpec = {
171        algName: "CMAC",
172        cipherName: "AES128",
173    };
174    let mac = cryptoFramework.createMac(spec);
175    // In this example, the message is of 43 bytes. After decoded in UTF-8 format, the message is also of 43 bytes.
176    let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee";
177    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
178    let updateLength = 20; // Pass in 20 bytes each time. You can set this parameter as required.
179    mac.initSync(key);
180    for (let i = 0; i < messageData.length; i += updateLength) {
181      let updateMessage = messageData.subarray(i, i + updateLength);
182      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
183      mac.updateSync(updateMessageBlob);
184    }
185    let macOutput = mac.doFinalSync();
186    console.info("[Sync]CMAC result: " + macOutput.data);
187    let macLen = mac.getMacLength();
188    console.info('CMAC len:' + macLen);
189  }
190  ```
191