• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 消息认证码计算CMAC
2
3CMAC通过使用分组密码(如AES)和一个密钥来生成认证码,确保消息在传输过程中未被篡改‌。
4
5## 开发步骤
6
7在调用update接口传入数据时,可以[一次性传入所有数据](#cmac一次性传入),也可以把数据人工分段,然后[分段update](#分段cmac)。对于同一段数据而言,是否分段,计算结果没有差异。对于数据量较大的数据,开发者可以根据实际需求选择是否分段传入。
8
9下面分别提供两种方式的示例代码。
10
11### CMAC(一次性传入)
12
131. 调用[cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac18),指定消息认证码算法CMAC,指定对称算法AES256,生成消息认证码实例(Mac)。
14
152. 调用[cryptoFramework.createSymKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesymkeygenerator)、[SymKeyGenerator.convertKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#convertkey-1),生成密钥算法为AES256的对称密钥(SymKey)。
16   生成对称密钥的详细开发指导,请参考[指定二进制数据生成对称密钥](crypto-convert-binary-data-to-sym-key.md)。
17
183. 调用[Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-6),指定共享对称密钥(SymKey),初始化Mac对象。
19
204. 调用[Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-8),传入自定义消息,进行消息认证码计算。单次update长度没有限制。
21
225. 调用[Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2),获取Mac计算结果。
23
246. 调用[Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength),获取Mac消息认证码的长度,单位为字节。
25
26- 以使用await方式一次性传入数据,获取消息认证码计算结果为例:
27
28  ```ts
29  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
30  import { buffer } from '@kit.ArkTS';
31
32  async function genSymKeyByData(symKeyData: Uint8Array) {
33    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
34    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
35    let symKey = await aesGenerator.convertKey(symKeyBlob);
36    console.info('convertKey success');
37    return symKey;
38  }
39  async function doCmac() {
40    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
41    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
42    let key = await genSymKeyByData(keyData);
43    let spec: cryptoFramework.CmacSpec = {
44        algName: "CMAC",
45        cipherName: "AES128",
46    };
47    let message = 'cmacTestMessage'; // 待进行CMAC的数据。
48    let mac = cryptoFramework.createMac(spec);
49    await mac.init(key);
50    // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制。
51    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
52    let macResult = await mac.doFinal();
53    console.info('CMAC result:' + macResult.data);
54    let macLen = mac.getMacLength();
55    console.info('CMAC len:' + macLen);
56  }
57  ```
58
59- 以使用同步方式一次性传入数据,获取消息认证码计算结果为例:
60
61  ```ts
62  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
63  import { buffer } from '@kit.ArkTS';
64
65  function genSymKeyByData(symKeyData: Uint8Array) {
66    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
67    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
68    let symKey =  aesGenerator.convertKeySync(symKeyBlob);
69    console.info('[Sync]convertKey success');
70    return symKey;
71  }
72  function doCmacBySync() {
73    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
74    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
75    let key = genSymKeyByData(keyData);
76    let spec: cryptoFramework.CmacSpec = {
77        algName: "CMAC",
78        cipherName: "AES128",
79    };
80    let message = 'cmacTestMessage'; // 待进行CMAC的数据。
81    let mac = cryptoFramework.createMac(spec);
82    mac.initSync(key);
83    // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制。
84    mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
85    let macResult = mac.doFinalSync();
86    console.info('[Sync]CMAC result:' + macResult.data);
87    let macLen = mac.getMacLength();
88    console.info('CMAC len:' + macLen);
89  }
90  ```
91
92### 分段CMAC
93
941. 调用[cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac18),指定消息认证码算法CMAC,指定对称算法AES256,生成消息认证码实例(Mac)。
95
962. 调用[cryptoFramework.createSymKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatesymkeygenerator)、[SymKeyGenerator.convertKey](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#convertkey-1),生成密钥算法为AES256的对称密钥(SymKey)。
97   生成对称密钥的详细开发指导,请参考[指定二进制数据生成对称密钥](crypto-convert-binary-data-to-sym-key.md)。
98
993. 调用[Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-7),指定共享对称密钥(SymKey),初始化Mac对象。
100
1014. 传入自定义消息,将一次传入数据量设置为20字节,多次调用[Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9),进行消息认证码计算。
102
1035. 调用[Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3),获取Mac计算结果。
104
1056. 调用[Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength),获取Mac消息认证码的长度,单位为字节。
106
107- 以使用await方式分段传入数据,获取消息认证码计算结果为例:
108
109  ```ts
110  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
111  import { buffer } from '@kit.ArkTS';
112
113  async function genSymKeyByData(symKeyData: Uint8Array) {
114    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
115    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
116    let symKey = await aesGenerator.convertKey(symKeyBlob);
117    console.info('convertKey success');
118    return symKey;
119  }
120  async function doLoopCmac() {
121    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
122    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
123    let key = await genSymKeyByData(keyData);
124    let spec: cryptoFramework.CmacSpec = {
125        algName: "CMAC",
126        cipherName: "AES128",
127    };
128    let mac = cryptoFramework.createMac(spec);
129    // 假设信息总共43字节,根据utf-8解码后,也是43字节。
130    let messageText = "aaaaa......bbbbb......ccccc......ddddd......eee";
131    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
132    let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求。
133    await mac.init(key);
134    for (let i = 0; i < messageData.length; i += updateLength) {
135      let updateMessage = messageData.subarray(i, i + updateLength);
136      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
137      await mac.update(updateMessageBlob);
138    }
139    let macOutput = await mac.doFinal();
140    console.info("CMAC result: " + macOutput.data);
141    let macLen = mac.getMacLength();
142    console.info('CMAC len:' + macLen);
143  }
144  ```
145
146- 以使用同步方式分段传入数据,获取消息认证码计算结果为例:
147
148  ```ts
149  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
150  import { buffer } from '@kit.ArkTS';
151
152  function genSymKeyByData(symKeyData: Uint8Array) {
153    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
154    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
155    let symKey = aesGenerator.convertKeySync(symKeyBlob);
156    console.info('[Sync]convertKey success');
157    return symKey;
158  }
159  function doLoopCmacBySync() {
160    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
161    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
162    let key = genSymKeyByData(keyData);
163    let spec: cryptoFramework.CmacSpec = {
164        algName: "CMAC",
165        cipherName: "AES128",
166    };
167    let mac = cryptoFramework.createMac(spec);
168    // 假设信息总共43字节,根据utf-8解码后,也是43字节。
169    let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee";
170    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
171    let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求。
172    mac.initSync(key);
173    for (let i = 0; i < messageData.length; i += updateLength) {
174      let updateMessage = messageData.subarray(i, i + updateLength);
175      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
176      mac.updateSync(updateMessageBlob);
177    }
178    let macOutput = mac.doFinalSync();
179    console.info("[Sync]CMAC result: " + macOutput.data);
180    let macLen = mac.getMacLength();
181    console.info('CMAC len:' + macLen);
182  }
183  ```
184