• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 加解密算法库框架开发指导
2
3> **说明**
4>
5> 本开发指导基于API version 9,OH SDK版本3.2.7以上,适用于JS语言开发
6
7## 使用密钥对象生成与转换操作
8
9**场景说明**
10
11使用密钥生成操作中,典型的场景有:
12
131. 随机生成算法库密钥对象。该对象可用于后续的加解密等操作。
142. 根据指定数据生成算法库密钥对象(也就是将外部或存储的二进制数据转换为算法库的密钥对象)。该对象可用于后续的加解密等操作。
153. 获取算法库密钥对象的二进制数据,用于存储或传输。
16> **说明**:密钥对象Key包括对称密钥SymKey和非对称密钥(公钥PubKey和私钥PriKey),其中公钥和私钥组成密钥对KeyPair。密钥之间的具体关系可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
17
18
19**接口及参数说明**
20
21详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
22
23以上场景涉及的常用接口如下表所示:
24
25|实例名|接口名|描述|
26|---|---|---|
27|cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|根据algName设置的非对称密钥规格,创建非对称密钥生成器对象|
28|cryptoFramework|createSymKeyGenerator(algName : string) : SymKeyGenerator|根据algName设置的对称密钥规格,创建对称密钥生成器对象|
29|AsyKeyGenerator|generateKeyPair(callback : AsyncCallback\<KeyPair>) : void|使用callback方式,随机生成非对称密钥对象KeyPair|
30|AsyKeyGenerator|generateKeyPair() : Promise\<KeyPair>|使用Promise方式,随机生成非对称密钥对象KeyPair|
31|SymKeyGenerator|generateSymKey(callback : AsyncCallback\<SymKey>) : void|使用callback方式,随机生成对称密钥对象SymKey|
32|SymKeyGenerator|generateSymKey() : Promise\<SymKey>|使用Promise方式,随机生成对称密钥对象SymKey|
33| AsyKeyGenerator          | convertKey(pubKey : DataBlob, priKey : DataBlob, callback : AsyncCallback\<KeyPair>) : void | 使用callback方式,根据指定的公钥和私钥二进制数据生成KeyPair对象<br/>(允许公钥/私钥为null,即只传入单一公钥或私钥,生成只携带公钥或私钥的KeyPair对象) |
34| AsyKeyGenerator          | convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair> | 使用Promise方式,根据指定的公钥和私钥二进制数据生成KeyPair对象<br/>(允许公钥/私钥为null,即只传入单一公钥或私钥,生成只携带公钥或私钥的KeyPair对象) |
35| SymKeyGenerator         | convertKey(key : DataBlob, callback : AsyncCallback\<SymKey>) : void| 使用callback方式,根据指定的二进制数据,生成对称密钥对象SymKey |
36| SymKeyGenerator         |convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair>| 使用Promise方式,根据指定的二进制数据,生成对称密钥对象SymKey |
37| Key | getEncoded() : DataBlob;  | 获取Key密钥对象的二进制数据(Key的子类实例包括对称密钥SymKey、公钥PubKey、私钥PriKey) |
38
39**开发步骤**
40
41示例1:随机生成非对称密钥KeyPair,并获得二进制数据(场景1、3)
42
431. 创建非对称密钥生成器;
442. 通过非对称密钥生成器随机生成非对称密钥;
453. 获取密钥对象的二进制数据;
46
47以使用Promise方式随机生成RSA密钥(1024位,素数个数为2)为例:
48
49```javascript
50import cryptoFramework from '@ohos.security.cryptoFramework';
51
52function generateAsyKey() {
53  // 创建非对称密钥生成器
54  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
55  // 通过非对称密钥生成器,随机生成非对称密钥
56  let keyGenPromise = rsaGenerator.generateKeyPair();
57  keyGenPromise.then( keyPair => {
58    globalKeyPair = keyPair;
59    let pubKey = globalKeyPair.pubKey;
60    let priKey = globalKeyPair.priKey;
61    // 获取非对称密钥的二进制数据
62    pkBlob = pubKey.getEncoded();
63    skBlob = priKey.getEncoded();
64    AlertDialog.show({ message : "pk bin data" + pkBlob.data} );
65    AlertDialog.show({ message : "sk bin data" + skBlob.data} );
66  })
67}
68```
69
70示例2:随机生成对称密钥SymKey,并获得二进制数据(场景1、3)
71
721. 创建对称密钥生成器;
732. 通过对称密钥生成器随机生成对称密钥;
743. 获取算法库密钥对象的二进制数据;
75
76以使用Promise方式随机生成AES密钥(256位)为例:
77
78```javascript
79import cryptoFramework from '@ohos.security.cryptoFramework';
80
81// 字节流以16进制输出
82function uint8ArrayToShowStr(uint8Array) {
83  return Array.prototype.map
84    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
85    .join('');
86}
87
88function testGenerateAesKey() {
89  // 创建对称密钥生成器
90  let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
91  // 通过密钥生成器随机生成对称密钥
92  let promiseSymKey = symKeyGenerator.generateSymKey();
93  promiseSymKey.then( key => {
94    // 获取对称密钥的二进制数据,输出长度为256bit的字节流
95    let encodedKey = key.getEncoded();
96    console.info('key hex:' + uint8ArrayToShowStr(encodedKey.data));
97  })
98}
99```
100
101示例3:根据指定的RSA非对称密钥二进制数据,生成KeyPair对象(场景2)
102
1031. 获取RSA公钥或私钥二进制数据,公钥需满足ASN.1语法、X.509规范、DER编码格式,私钥需满足ASN.1语法、PKCS#8规范、DER编码格式。
1042. 创建AsyKeyGenerator对象,调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。
105
106```javascript
107import cryptoFramework from '@ohos.security.cryptoFramework';
108
109function convertAsyKey() {
110  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024");
111  let pkval = new Uint8Array([48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,174,203,113,83,113,3,143,213,194,79,91,9,51,142,87,45,97,65,136,24,166,35,5,179,42,47,212,79,111,74,134,120,73,67,21,19,235,80,46,152,209,133,232,87,192,140,18,206,27,106,106,169,106,46,135,111,118,32,129,27,89,255,183,116,247,38,12,7,238,77,151,167,6,102,153,126,66,28,253,253,216,64,20,138,117,72,15,216,178,37,208,179,63,204,39,94,244,170,48,190,21,11,73,169,156,104,193,3,17,100,28,60,50,92,235,218,57,73,119,19,101,164,192,161,197,106,105,73,2,3,1,0,1]);
112  let pkBlob = {data : pkval};
113  rsaGenerator.convertKey(pkBlob, null, function(err, keyPair) {
114    if (keyPair == null) {
115      AlertDialog.show({message : "Convert keypair fail"});
116    }
117    AlertDialog.show({message : "Convert KeyPair success"});
118  })
119}
120```
121
122**说明**
123
124 当前convertKey操作,公钥只支持转换满足X.509规范的DER格式,私钥只支持PKCS#8规范的DER格式;
125
126示例4:根据指定的ECC非对称密钥二进制数据,生成KeyPair对象(场景2、3)
127
1281. 获取ECC二进制密钥数据,封装成DataBlob对象。
1292. 调用convertKey方法,传入公钥二进制和私钥二进制(二者非必选项,可只传入其中一个),转换为KeyPair对象。
130
131```javascript
132import cryptoFramework from "@ohos.security.cryptoFramework"
133
134function convertEccAsyKey() {
135    let pubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]);
136    let priKeyArray = new Uint8Array([48,49,2,1,1,4,32,115,56,137,35,207,0,60,191,90,61,136,105,210,16,27,4,171,57,10,61,123,40,189,28,34,207,236,22,45,223,10,189,160,10,6,8,42,134,72,206,61,3,1,7]);
137    let pubKeyBlob = { data: pubKeyArray };
138    let priKeyBlob = { data: priKeyArray };
139    let generator = cryptoFramework.createAsyKeyGenerator("ECC256");
140    generator.convertKey(pubKeyBlob, priKeyBlob, (error, data) => {
141        if (error) {
142            AlertDialog.show({message : "Convert keypair fail"});
143        }
144        AlertDialog.show({message : "Convert KeyPair success"});
145    })
146}
147```
148
149示例5:根据指定的对称密钥二进制数据,生成SymKey对象(场景2、3)
150
1511. 创建对称密钥生成器;
1522. 通过对称密钥生成器,根据指定的对称密钥二进制数据,生成SymKey对象;
1533. 获取算法库密钥对象的二进制数据;
154
155以使用callback方式生成3DES密钥(3DES密钥只能为192位)为例:
156
157```javascript
158import cryptoFramework from '@ohos.security.cryptoFramework';
159
160// 字节流以16进制输出
161function uint8ArrayToShowStr(uint8Array) {
162  return Array.prototype.map
163    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
164    .join('');
165}
166
167function genKeyMaterialBlob() {
168  let arr = [
169    0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56,
170    0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c,
171    0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72];    // keyLen = 192 (24 bytes)
172  let keyMaterial = new Uint8Array(arr);
173  return {data : keyMaterial};
174}
175
176function testConvertAesKey() {
177  // 生成对称密钥生成器
178  let symKeyGenerator = cryptoFramework.createSymKeyGenerator('3DES192');
179  // 根据用户指定的数据,生成对称密钥
180  let keyMaterialBlob = genKeyMaterialBlob();
181  try {
182    symKeyGenerator.convertKey(keyMaterialBlob, (error, key) => {
183      if (error) {    // 业务逻辑执行错误通过callback的第一个参数返回错误信息
184        console.error(`convertKey error, ${error.code}, ${error.message}`);
185        return;
186      }
187      console.info(`key algName: ${key.algName}`);
188      console.info(`key format: ${key.format}`);
189      let encodedKey = key.getEncoded();    // 获取对称密钥的二进制数据,输出长度为192bit的字节流
190      console.info('key getEncoded hex: ' + uint8ArrayToShowStr(encodedKey.data));
191    })
192  } catch (error) {    // 参数检查的错误以同步的方式立即抛出异常
193    console.error(`convertKey failed, ${error.code}, ${error.message}`);
194    return;
195  }
196}
197```
198
199## 使用加解密操作
200
201**场景说明**
202
203在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。使用加解密操作中,典型的场景有:
2041. 使用对称密钥的加解密操作
2052. 使用非对称密钥的加解密操作
206
207**接口及参数说明**
208
209详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。<br/>由于密码算法的复杂性,在选取不同规格和参数时,开发差异较大,无法通过代码示例一一列举,请仔细阅读API参考资料中的相关接口,确保使用正确。
210
211以上场景设计的常用接口如下表所示:
212
213|实例名|接口名|描述|
214|---|---|---|
215|cryptoFramework|createCipher(transformation : string) : Cipher|根据transformation设置的算法参数创建Cipher对象|
216|Cipher|init(opMode : CryptoMode, key : Key, params : ParamsSpec, callback : AsyncCallback\<void>) : void|使用callback方式设置密钥并初始化Cipher对象|
217|Cipher|init(opMode : CryptoMode, key : Key, params : ParamsSpec) : Promise\<void>|使用Promise方式设置密钥并初始化Cipher对象|
218|Cipher|update(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|使用callback方式添加加解密数据|
219|Cipher|update(data : DataBlob) : Promise\<DataBlob>|使用Promise方式添加加解密数据|
220|Cipher|doFinal(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|使用callback方式结束对所有数据的加解密|
221|Cipher|doFinal(data : DataBlob) : Promise\<DataBlob>|使用Promise方式结束对所有数据的加解密|
222
223**开发步骤**
224
225示例1:使用对称密钥的加解密操作
226
2271. 创建对称密钥生成器。
2282. 通过密钥生成器生成对称密钥。
2293. 创建加解密生成器。
2304. 通过加解密生成器加密或解密数据。
231
232以AES GCM以Promise方式加解密为例:
233
234```js
235import cryptoFramework from '@ohos.security.cryptoFramework';
236
237var globalCipher;
238var globalGcmParams;
239var globalKey;
240var globalCipherText;
241
242function genGcmParamsSpec() {
243  let arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0 , 0, 0]; // 12 bytes
244  let dataIv = new Uint8Array(arr);
245  let ivBlob = {data : dataIv};
246
247  arr = [0, 0, 0, 0 , 0, 0, 0, 0]; // 8 bytes
248  let dataAad = new Uint8Array(arr);
249  let aadBlob = {data : dataAad};
250
251  arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0]; // 16 bytes
252  let dataTag = new Uint8Array(arr);
253  let tagBlob = {data : dataTag};  // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中
254
255  let gcmParamsSpec = {iv : ivBlob, aad : aadBlob, authTag : tagBlob, algName : "GcmParamsSpec"};
256  return gcmParamsSpec;
257}
258
259// 可理解的字符串转成字节流
260function stringToUint8Array(str) {
261  let arr = [];
262  for (let i = 0, j = str.length; i < j; ++i) {
263    arr.push(str.charCodeAt(i));
264  }
265  return new Uint8Array(arr);
266}
267
268// 字节流以16进制输出
269function uint8ArrayToShowStr(uint8Array) {
270  return Array.prototype.map
271    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
272    .join('');
273}
274
275// 字节流转成可理解的字符串
276function uint8ArrayToString(array) {
277  let arrayString = '';
278  for (let i = 0; i < array.length; i++) {
279    arrayString += String.fromCharCode(array[i]);
280  }
281  return arrayString;
282}
283
284function genKeyMaterialBlob() {
285  let arr = [
286    0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56,
287    0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c,
288    0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72];    // keyLen = 192 (24 bytes)
289  let keyMaterial = new Uint8Array(arr);
290  return {data : keyMaterial};
291}
292
293
294// AES GCM模式示例,自动生成密钥(promise写法)
295function testAesGcm() {
296  return new Promise((resolve, reject) => {
297    setTimeout(() => {
298      resolve('testAesGcm');
299    }, 10)
300  }).then(() => {
301    // 生成对称密钥生成器
302    let symAlgName = 'AES128';
303    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
304    if (symKeyGenerator == null) {
305      console.error('createSymKeyGenerator failed');
306      return;
307    }
308    console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
309    // 通过密钥生成器随机生成128位长度的对称密钥
310    let promiseSymKey = symKeyGenerator.generateSymKey();
311    // 构造参数
312    globalGcmParams = genGcmParamsSpec();
313
314    // 生成加解密生成器
315    let cipherAlgName = 'AES128|GCM|PKCS7';
316    try {
317      globalCipher = cryptoFramework.createCipher(cipherAlgName);
318      console.info(`cipher algName: ${globalCipher.algName}`);
319    } catch (error) {
320      console.error(`createCipher failed, ${error.code}, ${error.message}`);
321      return;
322    }
323    return promiseSymKey;
324  }).then(key => {
325      let encodedKey = key.getEncoded();
326      console.info('key hex:' + uint8ArrayToShowStr(encodedKey.data));
327      globalKey = key;
328      return key;
329  }).then(key => {
330      // 初始化加解密操作环境:开始加密
331      let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
332      let promiseInit = globalCipher.init(mode, key, globalGcmParams);    // init
333      return promiseInit;
334  }).then(() => {
335      let plainText = {data : stringToUint8Array('this is test!')};
336      let promiseUpdate = globalCipher.update(plainText);   // update
337      return promiseUpdate;
338  }).then(updateOutput => {
339      globalCipherText = updateOutput;
340      let promiseFinal = globalCipher.doFinal(null);    // doFinal
341      return promiseFinal;
342  }).then(authTag => {
343      // GCM模式需要从doFinal的输出中取出加密后的认证信息并填入globalGcmParams,在解密时传入init()
344      globalGcmParams.authTag = authTag;
345      return;
346  }).then(() => {
347      // 初始化加解密操作环境:开始解密
348      let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
349      let promiseInit = globalCipher.init(mode, globalKey, globalGcmParams);    // init
350      return promiseInit;
351  }).then(() => {
352      let promiseUpdate = globalCipher.update(globalCipherText);    // update
353      return promiseUpdate;
354  }).then(updateOutput => {
355      console.info('decrypt plainText: ' + uint8ArrayToString(updateOutput.data));
356      let promiseFinal = globalCipher.doFinal(null);    // doFinal
357      return promiseFinal;
358  }).then(finalOutput => {
359      if (finalOutput == null) {  // 使用finalOutput.data前,先判断结果是否为null
360          console.info('GCM finalOutput is null');
361      }
362  }).catch(error => {
363      console.error(`catch error, ${error.code}, ${error.message}`);
364  })
365}
366```
367
368以3DES ECB以callback方式加解密(采用已有数据生成密钥)为例:
369
370```js
371import cryptoFramework from '@ohos.security.cryptoFramework';
372
373var globalCipher;
374var globalGcmParams;
375var globalKey;
376var globalCipherText;
377
378// 可理解的字符串转成字节流
379function stringToUint8Array(str) {
380  let arr = [];
381  for (let i = 0, j = str.length; i < j; ++i) {
382    arr.push(str.charCodeAt(i));
383  }
384  return new Uint8Array(arr);
385}
386
387// 字节流以16进制输出
388function uint8ArrayToShowStr(uint8Array) {
389  return Array.prototype.map
390    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
391    .join('');
392}
393
394// 字节流转成可理解的字符串
395function uint8ArrayToString(array) {
396  let arrayString = '';
397  for (let i = 0; i < array.length; i++) {
398    arrayString += String.fromCharCode(array[i]);
399  }
400  return arrayString;
401}
402
403function genKeyMaterialBlob() {
404  let arr = [
405    0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56,
406    0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c,
407    0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72];    // keyLen = 192 (24 bytes)
408  let keyMaterial = new Uint8Array(arr);
409  return {data : keyMaterial};
410}
411
412// 3DES ECB模式示例,采用已有数据生成密钥(callback写法)
413function test3DesEcb() {
414  // 生成对称密钥生成器
415  let symAlgName = '3DES192';
416  let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
417  if (symKeyGenerator == null) {
418    console.error('createSymKeyGenerator failed');
419    return;
420  }
421  console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
422
423  // 生成加解密生成器
424  let cipherAlgName = '3DES192|ECB|PKCS7';
425  try {
426    globalCipher = cryptoFramework.createCipher(cipherAlgName);
427    console.info(`cipher algName: ${globalCipher.algName}`);
428  } catch (error) {
429    console.error(`createCipher failed, ${error.code}, ${error.message}`);
430    return;
431  }
432
433  // 根据指定的数据,生成对称密钥
434  let keyMaterialBlob = genKeyMaterialBlob();
435  try {
436    symKeyGenerator.convertKey(keyMaterialBlob, (error, key) => {
437      if (error) {
438        console.error(`convertKey error, ${error.code}, ${error.message}`);
439        return;
440      }
441      console.info(`key algName: ${key.algName}`);
442      console.info(`key format: ${key.format}`);
443      let encodedKey = key.getEncoded();
444      console.info('key getEncoded hex: ' + uint8ArrayToShowStr(encodedKey.data));
445      globalKey = key;
446
447      // 初始化加解密操作环境:开始加密
448      let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
449      // init
450      globalCipher.init(mode, key, null, (err, ) => {
451        let plainText = {data : stringToUint8Array('this is test!')};
452        // update
453        globalCipher.update(plainText, (err, updateOutput) => {
454          globalCipherText = updateOutput;
455          //doFinal
456          globalCipher.doFinal(null, (err, finalOutput) => {
457            if (error) {
458              console.error(`doFinal error, ${error.code}, ${error.message}`);
459              return;
460            }
461            if (finalOutput != null) {
462              globalCipherText = Array.from(globalCipherText.data);
463              finalOutput = Array.from(finalOutput.data);
464              globalCipherText = globalCipherText.concat(finalOutput);
465              globalCipherText = new Uint8Array(globalCipherText);
466              globalCipherText = {data : globalCipherText};
467            }
468            // 初始化加解密操作环境:开始解密
469            let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
470            // init
471            globalCipher.init(mode, globalKey, null, (err, ) => {
472              // update
473              globalCipher.update(globalCipherText, (err, updateOutput) => {
474                console.info('decrypt plainText: ' + uint8ArrayToString(updateOutput.data));
475                // doFinal
476                globalCipher.doFinal(null, (error, finalOutput) => {
477                  if (finalOutput != null) {  // 使用finalOutput.data前,先判断结果是否为null
478                    console.info("decrypt plainText:" + uint8ArrayToString(finalOutput.data));
479                  }
480                })
481              })
482            })
483          })
484        })
485      })
486    })
487  } catch (error) {
488    console.error(`convertKey failed, ${error.code}, ${error.message}`);
489    return;
490  }
491}
492```
493以AES GCM以promise方式,分段update()实现加解密为例:
494
495```javascript
496import cryptoFramework from '@ohos.security.cryptoFramework';
497
498var globalCipher;
499var globalGcmParams;
500var globalKey;
501var globalCipherText;
502var globalPlainText;
503
504function genGcmParamsSpec() {
505  let arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0 , 0, 0]; // 12 bytes
506  let dataIv = new Uint8Array(arr);
507  let ivBlob = {data : dataIv};
508
509  arr = [0, 0, 0, 0 , 0, 0, 0, 0]; // 8 bytes
510  let dataAad = new Uint8Array(arr);
511  let aadBlob = {data : dataAad};
512
513  arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0]; // 16 bytes
514  let dataTag = new Uint8Array(arr);
515  let tagBlob = {data : dataTag};
516  let gcmParamsSpec = {iv : ivBlob, aad : aadBlob, authTag : tagBlob, algName : "GcmParamsSpec"};
517  return gcmParamsSpec;
518}
519
520// 字节流以16进制输出
521function uint8ArrayToShowStr(uint8Array) {
522  return Array.prototype.map
523    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
524    .join('');
525}
526
527// 字节流转成可理解的字符串
528function uint8ArrayToString(array) {
529  let arrayString = '';
530  for (let i = 0; i < array.length; i++) {
531    arrayString += String.fromCharCode(array[i]);
532  }
533  return arrayString;
534}
535
536// 算法库不限定update的次数和每次加解密的数据量,业务可根据自身内存情况对明文/密文进行多次分段。
537function testAesMultiUpdate() {
538  return new Promise((resolve, reject) => {
539    setTimeout(() => {
540      resolve('testAesMultiUpdate');
541    }, 10)
542  }).then(() => {
543    // 生成对称密钥生成器
544    let symAlgName = 'AES128';
545    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
546    if (symKeyGenerator == null) {
547      console.error('createSymKeyGenerator failed');
548      return;
549    }
550    console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
551    // 通过密钥生成器随机生成128位长度的对称密钥
552    let promiseSymKey = symKeyGenerator.generateSymKey();
553    // 构造参数
554    globalGcmParams = genGcmParamsSpec();
555
556    // 生成加解密生成器
557    let cipherAlgName = 'AES128|GCM|PKCS7';
558    try {
559      globalCipher = cryptoFramework.createCipher(cipherAlgName);
560      console.info(`cipher algName: ${globalCipher.algName}`);
561    } catch (error) {
562      console.error(`createCipher failed, ${error.code}, ${error.message}`);
563      return;
564    }
565    return promiseSymKey;
566  }).then(key => {
567    let encodedKey = key.getEncoded();
568    console.info('key hex:' + uint8ArrayToShowStr(encodedKey.data));
569    globalKey = key;
570    return key;
571  }).then(key => {
572    // 初始化加解密操作环境:开始加密
573    let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
574    let promiseInit = globalCipher.init(mode, key, globalGcmParams);    // init
575    return promiseInit;
576  }).then(async () => {
577    let plainText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee";   // 假设明文总共43字节
578    let messageArr = [];
579    let updateLength = 20;  // 假设每20字节分段update一次
580    globalCipherText = [];
581
582    for (let i = 0; i <= plainText.length; i++) {
583      if ((i % updateLength == 0 || i == plainText.length) && messageArr.length != 0) {
584        let message = new Uint8Array(messageArr);
585        let messageBlob = { data : message };
586        let updateOutput = await globalCipher.update(messageBlob);    // 分段update
587        // 把update的结果拼接起来,得到密文(有些情况下还需拼接doFinal的结果,这取决于分组模式
588        // 和填充模式,本例中GCM模式的doFinal结果只包含authTag而不含密文,所以不需要拼接)
589        globalCipherText = globalCipherText.concat(Array.from(updateOutput.data));
590        messageArr = [];
591      }
592      if (i < plainText.length) {
593        messageArr.push(plainText.charCodeAt(i));
594      }
595    }
596    return;
597  }).then(() => {
598    let promiseFinal = globalCipher.doFinal(null);    // doFinal
599    return promiseFinal;
600  }).then(authTag => {
601    // 获取加密后的认证信息
602    globalGcmParams.authTag = authTag;
603    return;
604  }).then(() => {
605    // 初始化加解密操作环境:开始解密
606    let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
607    let promiseInit = globalCipher.init(mode, globalKey, globalGcmParams);    // init
608    return promiseInit;
609  }).then(async () => {
610    let updateLength = 20;
611    let updateTimes = Math.ceil(globalCipherText.length / updateLength);  // 上取整
612    globalPlainText = "";
613    for (let i = 0; i < updateTimes; i++) {
614      let messageArr = globalCipherText.slice(i * updateLength, (i + 1) * updateLength);
615      let message = new Uint8Array(messageArr);
616      let messageBlob = { data : message };
617      let updateOutput = await globalCipher.update(messageBlob);    // 分段update
618      globalPlainText += uint8ArrayToString(updateOutput.data);     // 恢复出原始明文
619    }
620    return;
621  }).then(() => {
622    let promiseFinal = globalCipher.doFinal(null);      // doFinal
623    return promiseFinal;
624  }).then(finalOutput => {
625    if (finalOutput == null) {
626      console.info('GCM finalOutput is null');
627    }
628    console.info(`decrypt output: ${globalPlainText}`);
629  }).catch(error => {
630      console.error(`catch error, ${error.code}, ${error.message}`);
631  })
632}
633```
634
635示例2:使用非对称密钥的加解密操作
636
6371. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。
6382. 生成Cipher对象。通过createCipher接口创建Cipher对象,执行初始化操作,设置密钥及加解密模式。
6393. 执行加解密操作。通过调用Cipher对象提供的doFinal接口,执行加密操作生成密文或执行解密操作生成明文。
640
641```javascript
642import cryptoFramework from "@ohos.security.cryptoFramework"
643
644let plan = "This is cipher test.";
645
646function stringToUint8Array(str) {
647  var arr = [];
648  for (var i = 0, j = str.length; i < j; ++i) {
649    arr.push(str.charCodeAt(i));
650  }
651  var tmpArray = new Uint8Array(arr);
652  return tmpArray;
653}
654
655function encryptMessageProMise() {
656  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
657  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
658  let keyGenPromise = rsaGenerator.generateKeyPair();
659  keyGenPromise.then(rsaKeyPair => {
660    let pubKey = rsaKeyPair.pubKey;
661    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
662  }).then(() => {
663    let input = { data : stringToUint8Array(plan) };
664    return cipher.doFinal(input);
665  }).then(dataBlob => {
666    console.info("EncryptOutPut is " + dataBlob.data);
667  });
668}
669
670function encryptMessageCallback() {
671  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
672  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
673  rsaGenerator.generateKeyPair(function (err, keyPair) {
674    let pubKey = keyPair.pubKey;
675    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, function (err, data) {
676      let input = {data : stringToUint8Array(plan) };
677      cipher.doFinal(input, function (err, data) {
678        console.info("EncryptOutPut is " + data.data);
679      })
680    })
681  })
682}
683
684function decryptMessageProMise() {
685  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
686  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
687  let decoder = cryptoFramework.createCipher("RSA1024|PKCS1");
688  let keyGenPromise = rsaGenerator.generateKeyPair();
689  let keyPair;
690  let cipherDataBlob;
691  let input = { data : stringToUint8Array(plan) };
692  keyGenPromise.then(rsaKeyPair => {
693    keyPair = rsaKeyPair;
694    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
695  }).then(() => {
696    return cipher.doFinal(input);
697  }).then(dataBlob => {
698    console.info("EncryptOutPut is " + dataBlob.data);
699    AlertDialog.show({message : "output" + dataBlob.data});
700    cipherDataBlob = dataBlob;
701    return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
702  }).then(() => {
703    return decoder.doFinal(cipherDataBlob);
704  }).then(decodeData => {
705    if (decodeData.data.toString() === input.data.toString()) {
706      AlertDialog.show({message : "decrypt success"});
707      return;
708    }
709    AlertDialog.show({message : "decrypt fail"});
710  });
711}
712
713function decryptMessageCallback() {
714  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
715  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
716  let decoder = cryptoFramework.createCipher("RSA1024|PKCS1");
717  let plainText = "this is cipher text";
718  let input = {data : stringToUint8Array(plainText) };
719  let cipherData;
720  let keyPair;
721  rsaGenerator.generateKeyPair(function (err, newKeyPair) {
722    keyPair = newKeyPair;
723    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null, function (err, data) {
724      cipher.doFinal(input, function (err, data) {
725        AlertDialog.show({ message : "EncryptOutPut is " + data.data} );
726        cipherData = data;
727        decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null, function (err, data) {
728          decoder.doFinal(cipherData, function (err, data) {
729            if (input.data.toString() === data.data.toString()) {
730              AlertDialog.show({ message : "decrype success"} );
731              return;
732            }
733            AlertDialog.show({ message : "decrype fail"} );
734          });
735        });
736      });
737    });
738  });
739}
740```
741以RSA非对称加解密(多次调用doFinal实现分段)为例:
742```javascript
743import cryptoFramework from "@ohos.security.cryptoFramework"
744
745function stringToUint8Array(str) {
746  var arr = [];
747  for (var i = 0, j = str.length; i < j; ++i) {
748    arr.push(str.charCodeAt(i));
749  }
750  var tmpArray = new Uint8Array(arr);
751  return tmpArray;
752}
753
754// 字节流转成可理解的字符串
755function uint8ArrayToString(array) {
756  let arrayString = '';
757  for (let i = 0; i < array.length; i++) {
758    arrayString += String.fromCharCode(array[i]);
759  }
760  return arrayString;
761}
762
763function encryptLongMessagePromise() {
764  let globalPlainText = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
765  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
766  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
767  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
768  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
769  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
770  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
771  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";
772  let globalCipherOutput;
773  let globalDecodeOutput;
774  var globalKeyPair;
775  let plainTextSplitLen = 64; // RSA每次加解密允许的原文长度大小与密钥位数和填充模式等有关,详细规格内容见overview文档
776  let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文数据长度计算方式:密钥位数/8
777  let keyGenName = "RSA1024";
778  let cipherAlgName = "RSA1024|PKCS1";
779  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // 创建非对称密钥生成器对象
780  let cipher = cryptoFramework.createCipher(cipherAlgName); // 创建加密Cipher对象
781  let decoder = cryptoFramework.createCipher(cipherAlgName); // 创建解密Decoder对象
782  return new Promise((resolve, reject) => {
783    setTimeout(() => {
784      resolve("testRsaMultiDoFinal");
785    }, 10);
786  }).then(() => {
787    return asyKeyGenerator.generateKeyPair(); // 生成rsa密钥
788  }).then(keyPair => {
789    globalKeyPair = keyPair; // 保存到密钥对全局变量
790    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, globalKeyPair.pubKey, null);
791  }).then(async () => {
792    globalCipherOutput = [];
793    // 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128B长度的密文
794    for (let i = 0; i < (globalPlainText.length / plainTextSplitLen); i++) {
795      let tempStr = globalPlainText.substr(i * plainTextSplitLen, plainTextSplitLen);
796      let tempBlob = { data : stringToUint8Array(tempStr) };
797      let tempCipherOutput = await cipher.doFinal(tempBlob);
798      globalCipherOutput = globalCipherOutput.concat(Array.from(tempCipherOutput.data));
799    }
800    console.info(`globalCipherOutput len is ${globalCipherOutput.length}, data is: ${globalCipherOutput.toString()}`);
801    return;
802  }).then(() =>{
803    return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, globalKeyPair.priKey, null);
804  }).then(async() => {
805    globalDecodeOutput = [];
806    // 将密文按128B进行拆分解密,得到原文后进行拼接
807    for (let i = 0; i < (globalCipherOutput.length / cipherTextSplitLen); i++) {
808      let tempBlobData = globalCipherOutput.slice(i * cipherTextSplitLen, (i + 1) * cipherTextSplitLen);
809      let message = new Uint8Array(tempBlobData);
810      let tempBlob = { data : message };
811      let tempDecodeOutput = await decoder.doFinal(tempBlob);
812      globalDecodeOutput += uint8ArrayToString(tempDecodeOutput.data);
813    }
814    if (globalDecodeOutput === globalPlainText) {
815      console.info(`encode and decode success`);
816    } else {
817      console.info(`encode and decode error`);
818    }
819    return;
820  }).catch(error => {
821    console.error(`catch error, ${error.code}, ${error.message}`);
822  })
823}
824```
825
826**说明**
827
8281. 使用RSA加解密时,Cipher对象不可重复调用init方法初始化,在创建了一个加密Cipher对象后,如果要进行解密,则需要重新创建另一个Cipher对象执行解密操作。
8292. RSA加密有长度限制,允许加密明文的最大长度见[加解密算法库框架概述](cryptoFramework-overview.md)中的基本概念章节。
8303. RSA解密每次允许解密的密文长度为,RSA密钥的位数/8。
831
832## 使用签名验签操作
833
834**场景说明**
835
836当需要判断接收的数据是否被篡改且是否为指定对象发送的数据时,可以使用签名验签操作。使用签名验签操作中,典型的场景有:
8371. 使用RSA签名验签操作
8382. 使用ECC签名验签操作
839
840**接口及参数说明**
841
842详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。<br/>由于密码算法的复杂性,在选取不同规格和参数时,开发差异较大,无法通过代码示例一一列举,请仔细阅读API参考资料中的相关接口,确保使用正确。
843
844|实例名|接口名|描述|
845|---|---|---|
846|cryptoFramework|createSign(algName : string) : Sign|根据String设置的参数创建Sign对象|
847|Sign|init(priKey : PriKey, callback : AsyncCallback\<void>) : void|使用callback方式设置密钥并初始化Sign对象|
848|Sign|init(priKey : PriKey) : Promise\<void>|使用Promise方式设置密钥并初始化Sign对象|
849|Sign|update(data : DataBlob, callback : AsyncCallback\<void>) : void|使用callback方式添加签名数据|
850|Sign|update(data : DataBlob) : Promise\<void>|用Promise方式添加签名数据|
851|Sign|sign(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|使用callback方式签名所有数据|
852|Sign|sign(data : DataBlob) : Promise\<DataBlob>|使用Promise方式签名所有数据|
853|cryptoFramework|function createVerify(algName : string) : Verify|根据String设置的参数创建Verify对象|
854|Verify|init(priKey : PriKey, callback : AsyncCallback\<void>) : void|使用callback方式设置密钥并初始化Verify对象|
855|Verify|init(priKey : PriKey) : Promise\<void>|使用Promise方式设置密钥并初始化Verify对象|
856|Verify|update(data : DataBlob, callback : AsyncCallback\<void>) : void|使用callback方式添加验签数据|
857|Verify|update(data : DataBlob) : Promise\<void>|用Promise方式添加验签数据|
858|Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\<boolean>) : void|使用callback方式验签所有数据|
859|Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\<boolean>|使用Promise方式验签所有数据|
860
861**开发步骤**
862
863示例1:使用RSA签名验签操作
8641. 生成RSA密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成RSA非对称密钥。
8652. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。
8663. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用sign接口生成数据的签名。
8674. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。
8685. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用verify接口传入签名进行验签。
869```javascript
870import cryptoFramework from "@ohos.security.cryptoFramework"
871
872function stringToUint8Array(str) {
873	var arr = [];
874	for (var i = 0, j = str.length; i < j; ++i) {
875		arr.push(str.charCodeAt(i));
876	}
877	var tmpArray = new Uint8Array(arr);
878	return tmpArray;
879}
880
881let globalKeyPair;
882let SignMessageBlob;
883let plan1 = "This is Sign test plan1";
884let plan2 = "This is Sign test plan1";
885let input1 = { data : stringToUint8Array(plan1) };
886let input2 = { data : stringToUint8Array(plan2) };
887
888function signMessagePromise() {
889  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
890  let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256");
891  let keyGenPromise = rsaGenerator.generateKeyPair();
892  keyGenPromise.then( keyPair => {
893    globalKeyPair = keyPair;
894    let priKey = globalKeyPair.priKey;
895    return signer.init(priKey);
896  }).then(() => {
897    return signer.update(input1);
898  }).then(() => {
899    return signer.sign(input2);
900  }).then(dataBlob => {
901    SignMessageBlob = dataBlob;
902    console.info("sign output is " + SignMessageBlob.data);
903  });
904}
905
906function verifyMessagePromise() {
907  let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256");
908  let verifyInitPromise = verifyer.init(globalKeyPair.pubKey);
909  verifyInitPromise.then(() => {
910    return verifyer.update(input1);
911  }).then(() => {
912    return verifyer.verify(input2, SignMessageBlob);
913  }).then(res => {
914    console.log("Verify result is " + res);
915  });
916}
917
918function signMessageCallback() {
919  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
920  let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256");
921  rsaGenerator.generateKeyPair(function (err, keyPair) {
922    globalKeyPair = keyPair;
923    let priKey = globalKeyPair.priKey;
924    signer.init(priKey, function (err, data) {
925      signer.update(input1, function (err, data) {
926        signer.sign(input2, function (err, data) {
927          SignMessageBlob = data;
928          console.info("sign output is " + SignMessageBlob.data);
929        });
930      });
931    });
932  });
933}
934
935function verifyMessageCallback() {
936  let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256");
937  verifyer.init(globalKeyPair.pubKey, function (err, data) {
938    verifyer.update(input1, function(err, data) {
939      verifyer.verify(input2, SignMessageBlob, function(err, data) {
940        console.info("verify result is " + data);
941      });
942    });
943  })
944}
945```
946
947示例2:使用ECDSA操作
9481. 生成ECC密钥。通过createAsyKeyGenerator接口创建AsyKeyGenerator对象,并生成ECC非对称密钥。
9492. 生成Sign对象。通过createSign接口创建Sign对象,执行初始化操作并设置签名私钥。
9503. 执行签名操作。通过Sign类提供的update接口,添加签名数据,并调用doFinal接口生成数据的签名。
9514. 生成Verify对象。通过createVerify接口创建Verify对象,执行初始化操作并设置验签公钥。
9525. 执行验签操作。通过Verify类提供的update接口,添加签名数据,并调用doFinal接口传入签名进行验签。
953
954```javascript
955import cryptoFramework from "@ohos.security.cryptoFramework"
956
957function stringToUint8Array(str) {
958	var arr = [];
959	for (var i = 0, j = str.length; i < j; ++i) {
960		arr.push(str.charCodeAt(i));
961	}
962	var tmpArray = new Uint8Array(arr);
963	return tmpArray;
964}
965
966let globalKeyPair;
967let SignMessageBlob;
968let plan1 = "This is Sign test plan1";
969let plan2 = "This is Sign test plan1";
970let input1 = { data : stringToUint8Array(plan1) };
971let input2 = { data : stringToUint8Array(plan2) };
972
973function signMessagePromise() {
974  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
975  let signer = cryptoFramework.createSign("ECC256|SHA256");
976  let keyGenPromise = eccGenerator.generateKeyPair();
977  keyGenPromise.then( keyPair => {
978    globalKeyPair = keyPair;
979    let priKey = globalKeyPair.priKey;
980    return signer.init(priKey);
981  }).then(() => {
982    return signer.update(input1);
983  }).then(() => {
984    return signer.sign(input2);
985  }).then(dataBlob => {
986    SignMessageBlob = dataBlob;
987    console.info("sign output is " + SignMessageBlob.data);
988  });
989}
990
991function verifyMessagePromise() {
992  let verifyer = cryptoFramework.createVerify("ECC256|SHA256");
993  let verifyInitPromise = verifyer.init(globalKeyPair.pubKey);
994  verifyInitPromise.then(() => {
995    return verifyer.update(input1);
996  }).then(() => {
997    return verifyer.verify(input2, SignMessageBlob);
998  }).then(res => {
999    console.log("Verify result is " + res);
1000  });
1001}
1002
1003function signMessageCallback() {
1004  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
1005  let signer = cryptoFramework.createSign("ECC256|SHA256");
1006  eccGenerator.generateKeyPair(function (err, keyPair) {
1007    globalKeyPair = keyPair;
1008    let priKey = globalKeyPair.priKey;
1009    signer.init(priKey, function (err, data) {
1010      signer.update(input1, function (err, data) {
1011        signer.sign(input2, function (err, data) {
1012          SignMessageBlob = data;
1013          console.info("sign output is " + SignMessageBlob.data);
1014        });
1015      });
1016    });
1017  });
1018}
1019
1020function verifyMessageCallback() {
1021  let verifyer = cryptoFramework.createVerify("ECC256|SHA256");
1022  verifyer.init(globalKeyPair.pubKey, function (err, data) {
1023    verifyer.update(input1, function(err, data) {
1024      verifyer.verify(input2, SignMessageBlob, function(err, data) {
1025        console.info("verify result is " + data);
1026      });
1027    });
1028  })
1029}
1030```
1031以执行签名、验签操作时多次调用update实现分段为例:
1032
1033```javascript
1034import cryptoFramework from "@ohos.security.cryptoFramework"
1035
1036function stringToUint8Array(str) {
1037  var arr = [];
1038  for (var i = 0, j = str.length; i < j; ++i) {
1039    arr.push(str.charCodeAt(i));
1040  }
1041  var tmpArray = new Uint8Array(arr);
1042  return tmpArray;
1043}
1044
1045function signLongMessagePromise() {
1046  let globalPlainText = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1047  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1048  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1049  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1050  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1051  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1052  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1053  "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";
1054  let globalSignData;
1055  let textSplitLen = 64; // 自定义的数据拆分长度
1056  let keyGenName = "RSA1024";
1057  let cipherAlgName = "RSA1024|PKCS1|SHA256";
1058  let globalKeyPair;
1059  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // 创建非对称密钥生成器对象
1060  let signer = cryptoFramework.createSign(cipherAlgName); // 创建加密Cipher对象
1061  let verifier = cryptoFramework.createVerify(cipherAlgName); // 创建解密Decoder对象
1062  return new Promise((resolve, reject) => {
1063    setTimeout(() => {
1064      resolve("testRsaMultiUpdate");
1065    }, 10);
1066  }).then(() => {
1067    return asyKeyGenerator.generateKeyPair(); // 生成rsa密钥
1068  }).then(keyPair => {
1069    globalKeyPair = keyPair; // 保存到密钥对全局变量
1070    return signer.init(globalKeyPair.priKey);
1071  }).then(async () => {
1072    // 当原文过大时,可将原文按理想长度进行拆分,循环调用update添加原文
1073    for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1074      let tempStr = globalPlainText.substr(i * textSplitLen, textSplitLen);
1075      let tempBlob = { data : stringToUint8Array(tempStr) };
1076      await signer.update(tempBlob);
1077    }
1078    return signer.sign(null);
1079  }).then(data =>{
1080    globalSignData = data.data;
1081    console.info(`globalSignOutput len is ${globalSignData.length}, data is: ${globalSignData.toString()}`);
1082    return verifier.init(globalKeyPair.pubKey);
1083  }).then(async() => {
1084    // 将密文按128B进行拆分解密,得到原文后进行拼接
1085    for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1086      let tempData = globalPlainText.slice(i * textSplitLen, (i + 1) * textSplitLen);
1087      let tempBlob = { data : stringToUint8Array(tempData) };
1088      await verifier.update(tempBlob);
1089    }
1090    return verifier.verify(null, { data : globalSignData});
1091  }).then(res => {
1092    console.info(`verify res is ${res}`);
1093  }).catch(error => {
1094    console.error(`catch error, ${error.code}, ${error.message}`);
1095  })
1096}
1097```
1098
1099## 使用摘要操作
1100
1101**场景说明**
1102
1103用户指定摘要算法(如SHA256)生成Md实例,并输入单段或多段需要摘要的信息,进行摘要计算更新,并返回消息摘要计算结果,在指定算法后可获取当前算法名与摘要计算长度(字节)
1104
1105使用摘要操作的主要场景为:
1106
1107用户指定摘要算法(如SHA256)生成Md实例,并输入单段或多段需要摘要的信息,进行摘要计算更新,并返回消息摘要计算结果,在指定算法后可获取当前算法名与摘要计算长度(字节)
1108
1109**接口及参数说明**
1110
1111详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
1112
1113| 实例名          | 接口名                                                       | 描述                                               |
1114| --------------- | ------------------------------------------------------------ | -------------------------------------------------- |
1115| cryptoFramework | function createMd(algName : string) : Md;                    | 指定摘要算法,生成摘要操作实例Md                   |
1116| Md              | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | 接受用户输入数据,通过Callback的方式,异步更新摘要 |
1117| Md              | update(input : DataBlob) : Promise\<void>;                  | 接受用户输入数据,通过Promise的方式,异步更新摘要  |
1118| Md              | digest(callback : AsyncCallback\<DataBlob>) : void;         | 通过Callback的方式,返回结果                       |
1119| Md              | digest() : Promise\<DataBlob>;                              | 通过Promise的方式,返回结果                        |
1120| Md              | getMdLength() : number;                                      | 获取摘要的长度(由指定的摘要算法决定)             |
1121| Md              | readonly algName : string;                                   | 获取当前设置的摘要算法名                           |
1122
1123**开发步骤**
1124
11251. 设置算法,通过接口`createMd`生成摘要操作实例
11262. 接受用户数据,通过接口`update`,更新摘要,此步骤可重复
11273. 通过接口`digest`,返回摘要计算结果
11284. 获取当前摘要算法名与摘要计算长度
1129
1130```javascript
1131import cryptoFramework from "@ohos.security.cryptoFramework"
1132
1133// turn string into uint8Arr
1134function stringToUint8Array(str) {
1135  var arr = [];
1136  for (var i = 0, j = str.length; i < j; ++i) {
1137      arr.push(str.charCodeAt(i));
1138  }
1139  var tmpUint8Array = new Uint8Array(arr);
1140  return tmpUint8Array;
1141}
1142
1143// generate dataBlob with given length
1144function GenDataBlob(dataBlobLen) {
1145  var dataBlob;
1146  if (dataBlobLen == 12) {
1147      dataBlob = {data: stringToUint8Array("my test data")};
1148  } else {
1149      console.error("GenDataBlob: dataBlobLen is invalid");
1150      dataBlob = {data: stringToUint8Array("my test data")};
1151  }
1152  return dataBlob;
1153}
1154
1155// md with promise async
1156function doMdByPromise(algName) {
1157  var md;
1158  try {
1159    md = cryptoFramework.createMd(algName);
1160  } catch (error) {
1161    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1162  }
1163  console.error("[Promise]: Md algName is: " + md.algName);
1164  // 初次update
1165  var promiseMdUpdate = md.update(GenDataBlob(12));
1166  promiseMdUpdate.then(() => {
1167    // 可根据情况进行多次update
1168    promiseMdUpdate = md.update(GenDataBlob(12));
1169    return promiseMdUpdate;
1170  }).then(mdOutput => {
1171    var PromiseMdDigest = md.digest();
1172    return PromiseMdDigest;
1173  }).then(mdOutput => {
1174    console.error("[Promise]: MD result: " + mdOutput.data);
1175    var mdLen = md.getMdLength();
1176    console.error("[Promise]: MD len: " + mdLen);
1177  }).catch(error => {
1178    console.error("[Promise]: error: " + error.message);
1179  });
1180}
1181
1182// md with callback async
1183function doMdByCallback(algName) {
1184  var md;
1185  try {
1186    md = cryptoFramework.createMd(algName);
1187  } catch (error) {
1188    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1189  }
1190  console.error("[Callback]: Md algName is: " + md.algName);
1191  // 初次update
1192  md.update(GenDataBlob(12), (err,) => {
1193    if (err) {
1194      console.error("[Callback]: err: " + err.code);
1195    }
1196    // 可根据情况进行多次update
1197    md.update(GenDataBlob(12), (err1,) => {
1198      if (err1) {
1199        console.error("[Callback]: err: " + err1.code);
1200      }
1201      md.digest((err2, mdOutput) => {
1202        if (err2) {
1203          console.error("[Callback]: err: " + err2.code);
1204        } else {
1205          console.error("[Callback]: MD result: " + mdOutput.data);
1206          var mdLen = md.getMdLength();
1207          console.error("[Callback]: MD len: " + mdLen);
1208        }
1209      });
1210    });
1211  });
1212}
1213```
1214以MD更新时多次调用update实现分段为例:
1215```javascript
1216import cryptoFramework from "@ohos.security.cryptoFramework"
1217
1218async function updateData(index, obj, data) {
1219  console.error("update " + (index + 1) + " MB data...");
1220  return obj.update(data);
1221}
1222
1223function stringToUint8Array(str) {
1224  var arr = [];
1225  for (var i = 0, j = str.length; i < j; ++i) {
1226    arr.push(str.charCodeAt(i));
1227  }
1228  var tmpUint8Array = new Uint8Array(arr);
1229  return tmpUint8Array;
1230}
1231
1232function GenDataBlob(dataBlobLen) {
1233  var dataBlob;
1234  if (dataBlobLen == 12) {
1235    dataBlob = {data: stringToUint8Array("my test data")};
1236  } else {
1237    console.error("GenDataBlob: dataBlobLen is invalid");
1238    dataBlob = {data: stringToUint8Array("my test data")};
1239  }
1240  return dataBlob;
1241}
1242
1243function LoopMdPromise(algName, loopSize) {
1244  var md;
1245  try {
1246    md = cryptoFramework.createMd(algName);
1247  } catch (error) {
1248    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1249    return;
1250  }
1251  console.error("[Promise]: Md algName is: " + md.algName);
1252  var promiseMdUpdate = md.update(GenDataBlob(12));
1253  promiseMdUpdate.then(() => {
1254    var PromiseMdDigest = md.digest();
1255    return PromiseMdDigest;
1256  }).then(async () => {
1257    for (var i = 0; i < loopSize; i++) {
1258      await updateData(i, md, GenDataBlob(12));
1259    }
1260    var PromiseMdDigest = md.digest();
1261    return PromiseMdDigest;
1262  }).then(mdOutput => {
1263    console.error("[Promise]: MD result: " + mdOutput.data);
1264    var mdLen = md.getMdLength();
1265    console.error("[Promise]: MD len: " + mdLen);
1266  }).catch(error => {
1267    console.error("[Promise]: error: " + error.message);
1268  });
1269}
1270```
1271
1272## 使用密钥协商操作
1273
1274**场景说明**
1275
1276使用密钥协商操作中,典型的场景有:
1277
1278通信双方可以在一个公开的信道上通过相互传送一些消息,共同建立一个安全的共享秘密密钥。
1279
1280**接口及参数说明**
1281
1282详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
1283
1284|实例名|接口名|描述|
1285|---|---|---|
1286|cryptoFramework|createKeyAgreement(algName : string) : KeyAgreement|根据String设置的参数创建KeyAgreement对象|
1287|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\<DataBlob>) : void|使用callback方式进行密钥协商|
1288|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\<DataBlob>|使用Promise方式进行密钥协商|
1289
1290**开发步骤**
1291
12921. 通过createKeyAgreement接口创建KeyAgreement对象,用于后续的密钥协商操作。
12932. 调用KeyAgreement对象提供的generateSecret方法,传入对端的ECC公钥对象,以及本地生成的ECC私钥对象。
1294
1295```javascript
1296import cryptoFramework from "@ohos.security.cryptoFramework"
1297
1298let globalSelfPriKey;
1299let globalPeerPubKey;
1300
1301function ecdhPromise() {
1302  let peerPubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]);
1303  let peerPubKeyBlob = { data: peerPubKeyArray };
1304  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
1305  let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256");
1306  eccGenerator.convertKey(peerPubKeyBlob, null).then((peerKeyPair) => {
1307    globalPeerPubKey = peerKeyPair.pubKey;
1308    return eccGenerator.generateKeyPair();
1309  }).then((keyPair) => {
1310    globalSelfPriKey = keyPair.priKey;
1311    return eccKeyAgreement.generateSecret(globalSelfPriKey, globalPeerPubKey);
1312  }).then((secret) => {
1313    console.info("ecdh promise output is " + secret.data);
1314  }).catch((error) => {
1315    console.error("ecdh error.");
1316  });
1317}
1318
1319function ecdhCallback() {
1320  let peerPubKeyArray = new Uint8Array([48,89,48,19,6,7,42,134,72,206,61,2,1,6,8,42,134,72,206,61,3,1,7,3,66,0,4,83,96,142,9,86,214,126,106,247,233,92,125,4,128,138,105,246,162,215,71,81,58,202,121,26,105,211,55,130,45,236,143,55,16,248,75,167,160,167,106,2,152,243,44,68,66,0,167,99,92,235,215,159,239,28,106,124,171,34,145,124,174,57,92]);
1321  let peerPubKeyBlob = { data: peerPubKeyArray };
1322  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
1323  let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256");
1324  eccGenerator.convertKey(peerPubKeyBlob, null, function (err, peerKeyPair) {
1325    globalPeerPubKey = peerKeyPair.pubKey;
1326    eccGenerator.generateKeyPair(function (err, keyPair) {
1327      globalSelfPriKey = keyPair.priKey;
1328      eccKeyAgreement.generateSecret(globalSelfPriKey, globalPeerPubKey, function (err, secret) {
1329        if (err) {
1330          console.error("ecdh error.");
1331          return;
1332        }
1333        console.info("ecdh callback output is " + secret.data);
1334      });
1335    });
1336  })
1337}
1338```
1339
1340## 使用消息认证码操作
1341
1342**场景说明**
1343
1344消息认证码操作主要应用于身份认证的场景:
1345
1346Mac(message authentication code)可以对消息进行完整性校验,通过使用双方共享的密钥,识别出信息伪装篡改等行为
1347
1348用户指定摘要算法(如SHA256)生成消息认证码Mac实例,输入对称密钥初始化Mac,并传入单段或多段需要摘要的信息,进行消息认证码计算,并获取消息认证码计算结果,在指定算法后可获取当前算法名与消息认证码计算长度(字节)。
1349
1350**接口及参数说明**
1351
1352详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
1353
1354| 实例名          | 接口名                                                       | 描述                                                |
1355| --------------- | ------------------------------------------------------------ | --------------------------------------------------- |
1356| cryptoFramework | function createMac(algName : string) : Mac;                  | 指定摘要算法,生成消息认证码实例Mac                 |
1357| Mac             | init(key : SymKey, callback : AsyncCallback\<void>) : void; | 接收输入对称密钥,通过Callback的方式,异步初始化MAC |
1358| Mac             | init(key : SymKey) : Promise\<void>;                        | 接收输入对称密钥,通过Promise的方式,异步初始化MAC  |
1359| Mac             | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | 接受输入数据,通过Callback的方式,异步更新MAC       |
1360| Mac             | update(input : DataBlob) : Promise\<void>;                  | 接受输入数据,通过Promise的方式,异步更新MAC        |
1361| Mac             | doFinal(callback : AsyncCallback\<DataBlob>) : void;        | 通过Callback的方式,返回MAC计算结果                 |
1362| Mac             | doFinal() : Promise\<DataBlob>;                             | 通过Promise的方式,返回MAC计算结果                  |
1363| Mac             | getMacLength() : number;                                     | 获取MAC的长度(由指定的摘要算法决定)               |
1364| Mac             | readonly algName : string;                                   | 获取当前设置的摘要算法名                            |
1365
1366**开发步骤**
1367
13681. 设置算法,通过接口`createMac`生成消息认证码操作实例
13692. 接受输入对称密钥,通过接口`init`,初始化Mac
13703. 接受数据,通过接口`update`,更新Mac,此步骤可重复
13714. 通过接口`doFinal`,返回Mac计算结果
13725. 获取当前摘要算法名与Mac计算长度
1373
1374```javascript
1375import cryptoFramework from "@ohos.security.cryptoFramework"
1376
1377// turn string into uint8Arr
1378function stringToUint8Array(str) {
1379  var arr = [];
1380  for (var i = 0, j = str.length; i < j; ++i) {
1381      arr.push(str.charCodeAt(i));
1382  }
1383  var tmpUint8Array = new Uint8Array(arr);
1384  return tmpUint8Array;
1385}
1386
1387// generate blob with this func
1388function GenDataBlob(dataBlobLen) {
1389  var dataBlob;
1390  if (dataBlobLen == 12) {
1391      dataBlob = {data: stringToUint8Array("my test data")};
1392  } else {
1393      console.error("GenDataBlob: dataBlobLen is invalid");
1394      dataBlob = {data: stringToUint8Array("my test data")};
1395  }
1396  return dataBlob;
1397}
1398
1399function doHmacByPromise(algName) {
1400  var mac;
1401  try {
1402    mac = cryptoFramework.createMac(algName);
1403  } catch (error) {
1404    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1405  }
1406  console.error("[Promise]: Mac algName is: " + mac.algName);
1407  var KeyBlob = {
1408    data : stringToUint8Array("12345678abcdefgh")
1409  }
1410  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1411  var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
1412  promiseConvertKey.then(symKey => {
1413    var promiseMacInit = mac.init(symKey);
1414    return promiseMacInit;
1415  }).then(() => {
1416    // 初次update
1417    var promiseMacUpdate = mac.update(GenDataBlob(12));
1418    return promiseMacUpdate;
1419  }).then(() => {
1420    // 可根据情况进行多次update
1421    var promiseMacUpdate = mac.update(GenDataBlob(12));
1422    return promiseMacUpdate;
1423  }).then(() => {
1424    var PromiseMacDoFinal = mac.doFinal();
1425    return PromiseMacDoFinal;
1426  }).then(macOutput => {
1427    console.error("[Promise]: HMAC result: " + macOutput.data);
1428    var macLen = mac.getMacLength();
1429    console.error("[Promise]: MAC len: " + macLen);
1430  }).catch(error => {
1431    console.error("[Promise]: error: " + error.message);
1432  });
1433}
1434
1435// process by callback
1436function doHmacByCallback(algName) {
1437  var mac;
1438  try {
1439    mac = cryptoFramework.createMac(algName);
1440  } catch (error) {
1441    AlertDialog.show({message: "[Callback]: error code: " + error.code + ", message is: " + error.message});
1442    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1443  }
1444  var KeyBlob = {
1445    data : stringToUint8Array("12345678abcdefgh")
1446  }
1447  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1448  symKeyGenerator.convertKey(KeyBlob, (err, symKey) => {
1449    if (err) {
1450      console.error("[Callback]: err: " + err.code);
1451    }
1452    mac.init(symKey, (err1, ) => {
1453      if (err1) {
1454        console.error("[Callback]: err: " + err1.code);
1455      }
1456      // 初次update
1457      mac.update(GenDataBlob(12), (err2, ) => {
1458        if (err2) {
1459          console.error("[Callback]: err: " + err2.code);
1460        }
1461        // 可根据情况进行多次update
1462        mac.update(GenDataBlob(12), (err3, ) => {
1463          if (err3) {
1464            console.error("[Callback]: err: " + err3.code);
1465          }
1466          mac.doFinal((err4, macOutput) => {
1467            if (err4) {
1468              console.error("[Callback]: err: " + err4.code);
1469            } else {
1470              console.error("[Callback]: HMAC result: " + macOutput.data);
1471              var macLen = mac.getMacLength();
1472              console.error("[Callback]: MAC len: " + macLen);
1473            }
1474          });
1475        });
1476      });
1477    });
1478  });
1479}
1480```
1481以HMAC更新MAC时多次调用update实现分段为例:
1482```javascript
1483import cryptoFramework from "@ohos.security.cryptoFramework"
1484
1485async function updateData(index, obj, data) {
1486  console.error("update " + (index + 1) + " MB data...");
1487  return obj.update(data);
1488}
1489
1490function stringToUint8Array(str) {
1491  var arr = [];
1492  for (var i = 0, j = str.length; i < j; ++i) {
1493    arr.push(str.charCodeAt(i));
1494  }
1495  var tmpUint8Array = new Uint8Array(arr);
1496  return tmpUint8Array;
1497}
1498
1499function GenDataBlob(dataBlobLen) {
1500  var dataBlob;
1501  if (dataBlobLen == 12) {
1502    dataBlob = {data: stringToUint8Array("my test data")};
1503  } else {
1504    console.error("GenDataBlob: dataBlobLen is invalid");
1505    dataBlob = {data: stringToUint8Array("my test data")};
1506  }
1507  return dataBlob;
1508}
1509
1510function LoopHmacPromise(algName, loopSize) {
1511  var mac;
1512  try {
1513    mac = cryptoFramework.createMac(algName);
1514  } catch (error) {
1515    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1516    return;
1517  }
1518  console.error("[Promise]: Mac algName is: " + mac.algName);
1519  var KeyBlob = {
1520    data : stringToUint8Array("12345678abcdefgh")
1521  }
1522  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1523  var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
1524  promiseConvertKey.then(symKey => {
1525    var promiseMacInit = mac.init(symKey);
1526    return promiseMacInit;
1527  }).then(async () => {
1528    for (var i = 0; i < loopSize; i++) {
1529      await updateData(i, mac, GenDataBlob(12));
1530    }
1531    var promiseMacUpdate = mac.update(GenDataBlob(12));
1532    return promiseMacUpdate;
1533  }).then(() => {
1534    var PromiseMacDoFinal = mac.doFinal();
1535    return PromiseMacDoFinal;
1536  }).then(macOutput => {
1537    console.error("[Promise]: HMAC result: " + macOutput.data);
1538    var macLen = mac.getMacLength();
1539    console.error("[Promise]: MAC len: " + macLen);
1540  }).catch(error => {
1541    console.error("[Promise]: error: " + error.message);
1542  });
1543}
1544```
1545
1546
1547## 使用随机数操作
1548
1549**场景说明**
1550
1551使用随机数操作的主要场景为:
1552
1553- 用户生成随机数Random实例,输入随机数生成的长度(字节),生成指定长度的随机数。
1554- 用户使用生成的随机数作为参数,进行种子设置。
1555
1556**接口及参数说明**
1557
1558详细接口说明可参考[API参考](../reference/apis/js-apis-cryptoFramework.md)。
1559
1560| 实例名          | 接口名                                                       | 描述                                           |
1561| --------------- | ------------------------------------------------------------ | ---------------------------------------------- |
1562| cryptoFramework | function createRandom() : Random;                            | 生成随机数Random实例                           |
1563| Random          | generateRandom(len : number, callback: AsyncCallback\<DataBlob>) : void; | 接受输入长度,通过Callback,异步生成随机数   |
1564| Random          | generateRandom(len : number) : Promise\<DataBlob>;          | 接受输入长度,通过Promise,异步生成随机数      |
1565| Random          | setSeed(seed : DataBlob) : void;                            | 接受输入Blob,设置种子  |
1566
1567**开发步骤**
1568
15691. 通过接口`createRandom`生成随机数操作实例
15702. 接受输入长度,通过接口`generateRandom`,生成指定长度的随机数
15713. 接受DataBlob数据,通过接口`setSeed`,为随机数生成池设置种子
1572
1573```javascript
1574import cryptoFramework from "@ohos.security.cryptoFramework"
1575
1576// process by promise
1577function doRandByPromise(len) {
1578  var rand;
1579  try {
1580    rand = cryptoFramework.createRandom();
1581  } catch (error) {
1582    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1583  }
1584  var promiseGenerateRand = rand.generateRandom(len);
1585  promiseGenerateRand.then(randData => {
1586    console.error("[Promise]: rand result: " + randData.data);
1587      try {
1588          rand.setSeed(randData);
1589      } catch (error) {
1590          console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message);
1591      }
1592  }).catch(error => {
1593    console.error("[Promise]: error: " + error.message);
1594  });
1595}
1596
1597// process by callback
1598function doRandByCallback(len) {
1599  var rand;
1600  try {
1601    rand = cryptoFramework.createRandom();
1602  } catch (error) {
1603    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1604  }
1605  rand.generateRandom(len, (err, randData) => {
1606    if (err) {
1607      console.error("[Callback]: err: " + err.code);
1608    } else {
1609      console.error("[Callback]: generate random result: " + randData.data);
1610      try {
1611          rand.setSeed(randData);
1612      } catch (error) {
1613          console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message);
1614      }
1615    }
1616  });
1617}
1618```
1619