• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 消息认证码计算HMAC
2
3HMAC通过指定摘要算法,以通信双方共享密钥与消息作为输入,生成消息认证码用于检验传递报文的完整性。HMAC在消息摘要算法的基础上增加了密钥的输入,确保了信息的正确性。生成的消息认证码为固定长度。
4
5## 开发步骤
6
7在调用update接口传入数据时,可以[一次性传入所有数据](#hmac一次性传入),也可以把数据人工分段,然后[分段update](#分段hmac)。对于同一段数据而言,是否分段,计算结果没有差异。对于数据量较大的数据,开发者可以根据实际需求选择是否分段传入。
8
9下面分别提供两种方式的示例代码。
10
11### HMAC(一次性传入)
12
131. 调用[cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac),指定摘要算法SHA256,生成消息认证码实例(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),生成密钥算法为HMAC的对称密钥(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('HMAC');
35    let symKey = await aesGenerator.convertKey(symKeyBlob);
36    console.info('convertKey success');
37    return symKey;
38  }
39  async function doHmac() {
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 macAlgName = 'SHA256'; // 摘要算法名。
44    let message = 'hmacTestMessage'; // 待进行HMAC的数据。
45    let mac = cryptoFramework.createMac(macAlgName);
46    await mac.init(key);
47    // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制。
48    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
49    let macResult = await mac.doFinal();
50    console.info('HMAC result:' + macResult.data);
51    let macLen = mac.getMacLength();
52    console.info('HMAC len:' + macLen);
53  }
54  ```
55
56- 以使用同步方式一次性传入数据,获取消息认证码计算结果为例:
57
58  ```ts
59  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
60  import { buffer } from '@kit.ArkTS';
61
62  function genSymKeyByData(symKeyData: Uint8Array) {
63    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
64    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
65    let symKey =  aesGenerator.convertKeySync(symKeyBlob);
66    console.info('[Sync]convertKey success');
67    return symKey;
68  }
69  function doHmacBySync() {
70    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
71    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
72    let key = genSymKeyByData(keyData);
73    let macAlgName = 'SHA256'; // 摘要算法名。
74    let message = 'hmacTestMessage'; // 待进行HMAC的数据。
75    let mac = cryptoFramework.createMac(macAlgName);
76    mac.initSync(key);
77    // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制。
78    mac.updateSync({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
79    let macResult = mac.doFinalSync();
80    console.info('[Sync]HMAC result:' + macResult.data);
81    let macLen = mac.getMacLength();
82    console.info('HMAC len:' + macLen);
83  }
84  ```
85
86### 分段HMAC
87
881. 调用[cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac),指定摘要算法SHA256,生成消息认证码实例(Mac)。
89
902. 调用[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),生成密钥算法为HMAC的对称密钥(SymKey)。
91   生成对称密钥的详细开发指导,请参考[指定二进制数据生成对称密钥](crypto-convert-binary-data-to-sym-key.md)。
92
933. 调用[Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-7),指定共享对称密钥(SymKey),初始化Mac对象。
94
954. 传入自定义消息,将一次传入数据量设置为20字节,多次调用[Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-9),进行消息认证码计算。
96
975. 调用[Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-3),获取Mac计算结果。
98
996. 调用[Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength),获取Mac消息认证码的长度,单位为字节。
100
101- 以使用await方式分段传入数据,获取消息认证码计算结果为例:
102
103  ```ts
104  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
105  import { buffer } from '@kit.ArkTS';
106
107  async function genSymKeyByData(symKeyData: Uint8Array) {
108    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
109    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
110    let symKey = await aesGenerator.convertKey(symKeyBlob);
111    console.info('convertKey success');
112    return symKey;
113  }
114  async function doLoopHmac() {
115    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
116    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
117    let key = await genSymKeyByData(keyData);
118    let macAlgName = "SHA256"; // 摘要算法名。
119    let mac = cryptoFramework.createMac(macAlgName);
120    // 假设信息总共43字节,根据utf-8解码后,也是43字节。
121    let messageText = "aaaaa......bbbbb......ccccc......ddddd......eee";
122    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
123    let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求。
124    await mac.init(key);
125    for (let i = 0; i < messageData.length; i += updateLength) {
126      let updateMessage = messageData.subarray(i, i + updateLength);
127      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
128      await mac.update(updateMessageBlob);
129    }
130    let macOutput = await mac.doFinal();
131    console.info("HMAC result: " + macOutput.data);
132    let macLen = mac.getMacLength();
133    console.info('HMAC len:' + macLen);
134  }
135  ```
136
137- 以使用同步方式分段传入数据,获取消息认证码计算结果为例:
138
139  ```ts
140  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
141  import { buffer } from '@kit.ArkTS';
142
143  function genSymKeyByData(symKeyData: Uint8Array) {
144    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
145    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
146    let symKey = aesGenerator.convertKeySync(symKeyBlob);
147    console.info('[Sync]convertKey success');
148    return symKey;
149  }
150  function doLoopHmacBySync() {
151    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
152    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
153    let key = genSymKeyByData(keyData);
154    let macAlgName = "SHA256"; // 摘要算法名。
155    let mac = cryptoFramework.createMac(macAlgName);
156    // 假设信息总共43字节,根据utf-8解码后,也是43字节。
157    let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee";
158    let messageData = new Uint8Array(buffer.from(messageText, 'utf-8').buffer);
159    let updateLength = 20; // 假设以20字节为单位进行分段update,实际并无要求。
160    mac.initSync(key);
161    for (let i = 0; i < messageData.length; i += updateLength) {
162      let updateMessage = messageData.subarray(i, i + updateLength);
163      let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };
164      mac.updateSync(updateMessageBlob);
165    }
166    let macOutput = mac.doFinalSync();
167    console.info("[Sync]HMAC result: " + macOutput.data);
168    let macLen = mac.getMacLength();
169    console.info('HMAC len:' + macLen);
170  }
171  ```
172
173
174### HMAC(HmacSpec作为参数传入)
1751. 调用[cryptoFramework.createMac](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatemac),指定消息认证码算法HMAC,指定摘要算法SHA256,生成消息认证码实例(Mac)。
176
1772. 调用[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),生成密钥算法为HMAC的对称密钥(SymKey)。
178   生成对称密钥的详细开发指导,请参考[指定二进制数据生成对称密钥](crypto-convert-binary-data-to-sym-key.md)。
179
1803. 调用[Mac.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-6),指定共享对称密钥(SymKey),初始化Mac对象。
181
1824. 调用[Mac.update](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#update-8),传入自定义消息,进行消息认证码计算。单次update长度没有限制。
183
1845. 调用[Mac.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-2),获取Mac计算结果。
185
1866. 调用[Mac.getMacLength](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getmaclength),获取Mac消息认证码的长度,单位为字节。
187
188- 以使用await方式一次性传入数据,获取消息认证码计算结果为例:
189
190  ```ts
191  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
192  import { buffer } from '@kit.ArkTS';
193
194  async function genSymKeyByData(symKeyData: Uint8Array) {
195    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
196    let aesGenerator = cryptoFramework.createSymKeyGenerator('HMAC');
197    let symKey = await aesGenerator.convertKey(symKeyBlob);
198    console.info('convertKey success');
199    return symKey;
200  }
201  async function doHmac() {
202    // 把字符串按utf-8解码为Uint8Array,使用固定的128位的密钥,即16字节。
203    let keyData = new Uint8Array(buffer.from("12345678abcdefgh", 'utf-8').buffer);
204    let key = await genSymKeyByData(keyData);
205    let spec: cryptoFramework.HmacSpec = {
206        algName: "HMAC",
207        mdName: "SHA256",
208    };
209    let message = 'hmacTestMessage'; // 待进行HMAC的数据。
210    let mac = cryptoFramework.createMac(spec);
211    await mac.init(key);
212    // 数据量较少时,可以只做一次update,将数据全部传入,接口未对入参长度做限制。
213    await mac.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
214    let macResult = await mac.doFinal();
215    console.info('HMAC result:' + macResult.data);
216    let macLen = mac.getMacLength();
217    console.info('HMAC len:' + macLen);
218  }
219  ```