• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Crypto Framework Development
2
3> **NOTE**
4>
5> This guide applies to JS development using OpenHarmony API version 9 and SDK version 3.2.7 or later.
6
7## Generating and Converting a Key
8
9**When to Use**
10
11Typical key generation operations involve the following:
12
131. Randomly create a key instance for subsequent encryption and decryption.
142. Convert external or stored binary data into a key instance for subsequent encryption and decryption.
153. Obtain the binary data of a key for storage or transmission.
16> **NOTE**<br>The key instance can be a symmetric key instance (**SymKey**) or an asymmetric key pair instance (**KeyPair**). The **KeyPair** instance consists a public key (**PubKey**) and a private key (**PriKey**). For details about the relationship between keys, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
17
18
19**Available APIs**
20
21For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
22
23The table below describes the APIs used in this guide.
24
25|Instance|API|Description|
26|---|---|---|
27|cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|Creates an **AsyKeyGenerator** instance.|
28|cryptoFramework|createSymKeyGenerator(algName : string) : SymKeyGenerator|Creates a **SymKeyGenerator** instance.|
29|AsyKeyGenerator|generateKeyPair(callback : AsyncCallback\<KeyPair>) : void|Generates an asymmetric key pair randomly. This API uses an asynchronous callback to return the result.|
30|AsyKeyGenerator|generateKeyPair() : Promise\<KeyPair>|Generates an asymmetric key pair randomly. This API uses a promise to return the result.|
31|SymKeyGenerator|generateSymKey(callback : AsyncCallback\<SymKey>) : void|Generates a symmetric key randomly. This API uses an asynchronous callback to return the result.|
32|SymKeyGenerator|generateSymKey() : Promise\<SymKey>|Generates a symmetric key randomly. This API uses a promise to return the result.|
33| AsyKeyGenerator          | convertKey(pubKey : DataBlob, priKey : DataBlob, callback : AsyncCallback\<KeyPair>) : void | Converts binary data into a key pair. This API uses an asynchronous callback to return the result.<br>(**pubKey** or **priKey** can be **null**. That is, you can pass in only **pubKey** or **priKey**. As a result, the returned **KeyPair** instance contains only the public or private key.)|
34| AsyKeyGenerator          | convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair> | Converts binary data into a key pair. This API uses a promise to return the result.<br>(**pubKey** or **priKey** can be **null**. That is, you can pass in only **pubKey** or **priKey**. As a result, the returned **KeyPair** instance contains only the public or private key.)|
35| SymKeyGenerator         | convertKey(key : DataBlob, callback : AsyncCallback\<SymKey>) : void| Converts binary data into a symmetric key. This API uses an asynchronous callback to return the result.|
36| SymKeyGenerator         |convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair>| Converts binary data into a symmetric key. This API uses a promise to return the result.|
37| Key | getEncoded() : DataBlob;  | Obtains the binary data of a key. (The child class instances of **Key** include **SymKey**, **PubKey**, and **PriKey**.)|
38
39**How to Develop**
40
41Example 1: Randomly generate an asymmetric key pair and obtain its binary data.
42
431. Create an **AsyKeyGenerator** instance.
442. Randomly generate an asymmetric key pair using **AsyKeyGenerator**.
453. Obtain binary data of the key pair generated.
46
47The following sample code demonstrates how to randomly generate an RSA key (1024 bits and two primes) using promise-based APIs.
48
49```javascript
50import cryptoFramework from '@ohos.security.cryptoFramework';
51
52function generateAsyKey() {
53  // Create an AsyKeyGenerator instance.
54  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
55  // Use the key generator to randomly generate an asymmetric key pair.
56  let keyGenPromise = rsaGenerator.generateKeyPair();
57  keyGenPromise.then( keyPair => {
58    globalKeyPair = keyPair;
59    let pubKey = globalKeyPair.pubKey;
60    let priKey = globalKeyPair.priKey;
61    // Obtain the binary data of the asymmetric key pair.
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
70Example 2: Randomly generate a symmetric key and obtain its binary data.
71
721. Create a **SymKeyGenerator** instance.
732. Randomly generate a symmetric key using **SymKeyGenerator**.
743. Obtain binary data of the key generated.
75
76The following example demonstrates how to randomly generate a 256-bit AES key using promise-based APIs.
77
78```javascript
79import cryptoFramework from '@ohos.security.cryptoFramework';
80
81// Output the byte streams in hexadecimal format.
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  // Create a SymKeyGenerator instance.
90  let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
91  // Use the key generator to randomly generate a symmetric key.
92  let promiseSymKey = symKeyGenerator.generateSymKey();
93  promiseSymKey.then( key => {
94    // Obtain the binary data of the symmetric key and output a 256-bit byte stream.
95    let encodedKey = key.getEncoded();
96    console.info('key hex:' + uint8ArrayToShowStr(encodedKey.data));
97  })
98}
99```
100
101Example 3: Generate an asymmetric key pair from the binary RSA key data.
102
1031. Obtain the binary data of the RSA public or private key. The public key must comply with the ASN.1 syntax, X.509 specifications, and DER encoding format. The private key must comply with the ASN.1 syntax, PKCS #8 specifications, and DER encoding format.
1042. Create an **AsyKeyGenerator** instance and call **convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
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> **NOTE**
123>
124> The public key material to be converted in **convertKey()** must be in the DER format complying with X.509 specifications, and the private key material must be in the DER format complying with PKCS #8 specifications.
125
126Example 4: Generate an asymmetric key pair from the binary ECC key data.
127
1281. Obtain the ECC binary key data and encapsulate it into a **DataBlob** instance.
1292. Call **convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
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
149Example 5: Generate a symmetric key from binary data.
150
1511. Create a **SymKeyGenerator** instance.
1522. Generate a symmetric key from the binary data passed in.
1533. Obtain binary data of the key generated.
154
155The following example demonstrates how to generate a 3DES key (192 bits only) using callback-based APIs.
156
157```javascript
158import cryptoFramework from '@ohos.security.cryptoFramework';
159
160// Output the byte streams in hexadecimal format.
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  // Create a SymKeyGenerator instance.
178  let symKeyGenerator = cryptoFramework.createSymKeyGenerator('3DES192');
179  // Generate a symmetric key based on the specified data.
180  let keyMaterialBlob = genKeyMaterialBlob();
181  try {
182    symKeyGenerator.convertKey(keyMaterialBlob, (error, key) => {
183      if (error) {    // If the service logic fails to be executed, return the error information in the first parameter of the 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();    // Obtain the binary data of the symmetric key and output a 192-bit byte stream.
190      console.info('key getEncoded hex: ' + uint8ArrayToShowStr(encodedKey.data));
191    })
192  } catch (error) {    // Throw an exception immediately in synchronous mode when an error is detected during the parameter check.
193    console.error(`convertKey failed, ${error.code}, ${error.message}`);
194    return;
195  }
196}
197```
198
199## Encrypting and Decrypting Data
200
201**When to Use**
202
203Important data needs to be encrypted in data storage or transmission for security purposes. Typical encryption and decryption operations involve the following:
2041. Encrypt and decrypt data using a symmetric key.
2052. Encrypt and decrypt data using an asymmetric key pair.
206
207**Available APIs**
208
209For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to the complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs in the API reference to ensure correct use of these APIs.
210
211The table below describes the APIs used in this guide.
212
213|Instance|API|Description|
214|---|---|---|
215|cryptoFramework|createCipher(transformation : string) : Cipher|Creates a **Cipher** instance.|
216|Cipher|init(opMode : CryptoMode, key : Key, params : ParamsSpec, callback : AsyncCallback\<void>) : void|Sets a key and initializes the **Cipher** instance. This API uses an asynchronous callback to return the result.|
217|Cipher|init(opMode : CryptoMode, key : Key, params : ParamsSpec) : Promise\<void>|Sets a key and initializes the **Cipher** instance. This API uses a promise to return the result.|
218|Cipher|update(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Updates the data for encryption and decryption. This API uses an asynchronous callback to return the result.|
219|Cipher|update(data : DataBlob) : Promise\<DataBlob>|Updates the data for encryption and decryption. This API uses a promise to return the result.|
220|Cipher|doFinal(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Finalizes the encryption or decryption. This API uses an asynchronous callback to return the result.|
221|Cipher|doFinal(data : DataBlob) : Promise\<DataBlob>|Finalizes the encryption or decryption. This API uses a promise to return the result.|
222
223**How to Develop**
224
225Example 1: Encrypt and decrypt data using a symmetric key.
226
2271. Create a **SymKeyGenerator** instance.
2282. Use the key generator to generate a symmetric key.
2293. Create a **Cipher** instance.
2304. Encrypt or decrypt data.
231
232The following example demonstrates how to use the AES-GCM to encrypt and decrypt data with promise-based APIs.
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};  // The authTag of GCM is obtained by doFinal() in encryption and passed in params of init() in decryption.
254
255  let gcmParamsSpec = {iv : ivBlob, aad : aadBlob, authTag : tagBlob, algName : "GcmParamsSpec"};
256  return gcmParamsSpec;
257}
258
259// Convert strings in plaintext into byte streams.
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// Output the byte streams in hexadecimal format.
269function uint8ArrayToShowStr(uint8Array) {
270  return Array.prototype.map
271    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
272    .join('');
273}
274
275// Convert byte streams into strings in plaintext.
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// Automatically generate a key in AES GCM mode and return the result in a promise.
295function testAesGcm() {
296  return new Promise((resolve, reject) => {
297    setTimeout(() => {
298      resolve('testAesGcm');
299    }, 10)
300  }).then(() => {
301    // Create a SymKeyGenerator instance.
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    // Use the key generator to randomly generate a 128-bit symmetric key.
310    let promiseSymKey = symKeyGenerator.generateSymKey();
311    // Constructor
312    globalGcmParams = genGcmParamsSpec();
313
314    // Create a Cipher instance.
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      // Initialize the cipher environment and start encryption.
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      // In GCM mode, the encrypted authentication information needs to be obtained from the output of doFinal() and passed in globalGcmParams of init() in decryption.
344      globalGcmParams.authTag = authTag;
345      return;
346  }).then(() => {
347      // Initialize the cipher environment and start decryption.
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) {  // Check whether the result is null before using finalOutput.data.
360          console.info('GCM finalOutput is null');
361      }
362  }).catch(error => {
363      console.error(`catch error, ${error.code}, ${error.message}`);
364  })
365}
366```
367
368The following example demonstrates how to use the the 3DES ECB to convert existing data into a key and encrypt and decrypt data using callback-based APIs.
369
370```js
371import cryptoFramework from '@ohos.security.cryptoFramework';
372
373var globalCipher;
374var globalGcmParams;
375var globalKey;
376var globalCipherText;
377
378// Convert strings in plaintext into byte streams.
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// Output the byte streams in hexadecimal format.
388function uint8ArrayToShowStr(uint8Array) {
389  return Array.prototype.map
390    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
391    .join('');
392}
393
394// Convert byte streams into strings in plaintext.
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// Use the 3DES ECB to Generate a key from the existing data and encrypt and decrypt data using callback-based APIs.
413function test3DesEcb() {
414  // Create a SymKeyGenerator instance.
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  // Create a Cipher instance.
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  // Generate a symmetric key based on the specified data.
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      // Initialize the cipher environment and start encryption.
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            // Initialize the cipher environment and start decryption.
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) {  // Check whether the result is null before using finalOutput.data.
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```
493The following example demonstrates how to call **update()** multiple times to implement AES GCM encryption and decryption by using promise-based APIs.
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// Output the byte streams in hexadecimal format.
521function uint8ArrayToShowStr(uint8Array) {
522  return Array.prototype.map
523    .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2))
524    .join('');
525}
526
527// Convert byte streams into strings in plaintext.
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// The algorithm library does not limit the number of update() times and the amount of data to be encrypted and decrypted each time. You can use update() multiple times based on the memory usage.
537function testAesMultiUpdate() {
538  return new Promise((resolve, reject) => {
539    setTimeout(() => {
540      resolve('testAesMultiUpdate');
541    }, 10)
542  }).then(() => {
543    // Create a SymKeyGenerator instance.
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    // Use the key generator to randomly generate a 128-bit symmetric key.
552    let promiseSymKey = symKeyGenerator.generateSymKey();
553    // Constructor
554    globalGcmParams = genGcmParamsSpec();
555
556    // Create a Cipher instance.
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    // Initialize the cipher environment and start encryption.
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"; // Assume that the plaintext contains 43 bytes.
578    let messageArr = [];
579    let updateLength = 20; // Pass in 20 bytes by update() each time.
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 by segment.
587        // Combine the result of each update() to obtain the ciphertext. In certain cases, the doFinal() results need to be combined, which depends on the cipher block mode
588        // and padding mode you use. In this example, the doFinal() result in GCM mode contains authTag but not ciphertext. Therefore, there is no need to combine the results.
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    // Obtain the authentication information after encryption.
602    globalGcmParams.authTag = authTag;
603    return;
604  }).then(() => {
605    // Initialize the cipher environment and start decryption.
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);  // Round up to the nearest integer.
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); // Pass in data by segment.
618      globalPlainText += uint8ArrayToString(updateOutput.data);     // Restore the original plaintext.
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
635Example 2: Encrypt and decrypt data using an asymmetric key pair.
636
6371. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
6382. Create a **Cipher** instance.<br>Call **createCipher()** to create a **Cipher** instance, and set the key and encryption/decryption mode.
6393. Perform encryption and decryption operations.<br>Call **doFinal()** provided by the **Cipher** instance to encrypt data or decrypt data.
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```
741The following example demonstrates how to implement RSA asymmetric encryption and decryption (**doFinal()** is called multiple times).
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// Convert byte streams into strings in plaintext.
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; // The length of the plaintext to be encrypted or decrypted each time by RSA depends on the number of key bits and padding mode. For details, see the Crypto Framework Overview.
776  let cipherTextSplitLen = 128; // Length of the ciphertext = Number of key bits/8
777  let keyGenName = "RSA1024";
778  let cipherAlgName = "RSA1024|PKCS1";
779  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // Create an AsyKeyGenerator object.
780  let cipher = cryptoFramework.createCipher(cipherAlgName); // Create a Cipher object.
781  let decoder = cryptoFramework.createCipher(cipherAlgName); // Create a Decoder object.
782  return new Promise((resolve, reject) => {
783    setTimeout(() => {
784      resolve("testRsaMultiDoFinal");
785    }, 10);
786  }).then(() => {
787    return asyKeyGenerator.generateKeyPair(); // Generate an RSA key.
788  }).then(keyPair => {
789    globalKeyPair = keyPair; // Save the key to global variables.
790    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, globalKeyPair.pubKey, null);
791  }).then(async () => {
792    globalCipherOutput = [];
793    // Split the plaintext by 64 characters and cyclically call doFinal() to encrypt the plaintext. If a 1024-bit key is used, 128-byte ciphertext is generated each time.
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    // Split and decrypt the ciphertext by 128 bytes, and combine the plaintext obtained each time.
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> **NOTE**
827>
828> - In RSA encryption and decryption, **init()** cannot be repeatedly called to initialize the **Cipher** instance. You must create a **Cipher** instance for each encryption and decryption.
829> - The RSA encryption has a limit on the length of the plaintext to be encrypted. For details, see "Basic Concepts" in [Cryptographic Framework Overview](cryptoFramework-overview.md).
830> - In RSA decryption, the length of the ciphertext to be decrypted each time is the number of bits of the RSA key divided by 8.
831
832## Generating and Verifying a Signature
833
834**When to Use**
835
836A digital signature can be used to verify the authenticity of a message. Typical signing and signature verification operations involve the following:
837- Use the RSA to generate and verify a signature.
838- Use the ECC to generate and verify a signature.
839
840**Available APIs**
841
842For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md). <br>Due to the complexity of cryptographic algorithms, the implementation varies depending on the specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs in the API reference to ensure correct use of these APIs.
843
844|Instance|API|Description|
845|---|---|---|
846|cryptoFramework|createSign(algName : string) : Sign|Creates a **Sign** instance.|
847|Sign|init(priKey : PriKey, callback : AsyncCallback\<void>) : void|Sets a key and initializes the **Sign** instance. This API uses an asynchronous callback to return the result.|
848|Sign|init(priKey : PriKey) : Promise\<void>|Sets a key and initializes the **Sign** instance. This API uses a promise to return the result.|
849|Sign|update(data : DataBlob, callback : AsyncCallback\<void>) : void|Updates the data for signing. This API uses an asynchronous callback to return the result.|
850|Sign|update(data : DataBlob) : Promise\<void>|Updates the data for signing. This API uses a promise to return the result.|
851|Sign|sign(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Signs the data. This API uses an asynchronous callback to return the result.|
852|Sign|sign(data : DataBlob) : Promise\<DataBlob>|Signs the data. This API uses a promise to return the result.|
853|cryptoFramework|function createVerify(algName : string) : Verify|Creates a **Verify** instance.|
854|Verify|init(priKey : PriKey, callback : AsyncCallback\<void>) : void|Sets a key and initializes the **Verify** instance. This API uses an asynchronous callback to return the result.|
855|Verify|init(priKey : PriKey) : Promise\<void>|Sets a key and initializes the **Verify** instance. This API uses a promise to return the result.|
856|Verify|update(data : DataBlob, callback : AsyncCallback\<void>) : void|Updates the data for signature verification. This API uses an asynchronous callback to return the result.|
857|Verify|update(data : DataBlob) : Promise\<void>|Updates the data for signature verification. This API uses a promise to return the result.|
858|Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\<boolean>) : void|Verifies the signature. This API uses an asynchronous callback to return the result.|
859|Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\<boolean>|Verifies the signature. This API uses a promise to return the result.|
860
861**How to Develop**
862
863Example 1: Use the RSA to generate and verify a signature.
8641. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
8652. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
8663. Generate a signature.<br>Call **update()** provided by the **Sign** class to add the data for signing and call **sign()** to generate a signature.
8674. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
8685. Verify the signature.<br>Call **update()** provided by the **Verify** class to add signature data and call **verify()** to verify the signature.
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
947Example 2: Use the ECDSA to generate and verify a signature.
9481. Generate an ECC key.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an ECC asymmetric key pair.
9492. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
9503. Generate a signature.<br>Call **update()** provided by the **Sign** class to add the data for signing and call **doFinal()** to generate a signature.
9514. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
9525. Verify the signature.<br>Call **update()** provided by the **Verify** class to add signature data and call **doFinal()** to verify the signature.
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```
1031The following example demonstrates how to call **update()** multiple times to implement signing and signature verification.
1032```javascript
1033import cryptoFramework from "@ohos.security.cryptoFramework"
1034
1035function stringToUint8Array(str) {
1036  var arr = [];
1037  for (var i = 0, j = str.length; i < j; ++i) {
1038    arr.push(str.charCodeAt(i));
1039  }
1040  var tmpArray = new Uint8Array(arr);
1041  return tmpArray;
1042}
1043
1044function signLongMessagePromise() {
1045  let globalPlainText = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1046  "This is a long plainTest! 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  let globalSignData;
1054  let textSplitLen = 64; // Customized data splitting length.
1055  let keyGenName = "RSA1024";
1056  let cipherAlgName = "RSA1024|PKCS1|SHA256";
1057  let globalKeyPair;
1058  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // Create an AsyKeyGenerator object.
1059  let signer = cryptoFramework.createSign(cipherAlgName); //Create a cipher object for encryption.
1060  let verifier = cryptoFramework.createVerify(cipherAlgName); // Create a Decoder object for decryption.
1061  return new Promise((resolve, reject) => {
1062    setTimeout(() => {
1063      resolve("testRsaMultiUpdate");
1064    }, 10);
1065  }).then(() => {
1066    return asyKeyGenerator.generateKeyPair(); // Generate an RSA key.
1067  }).then(keyPair => {
1068    globalKeyPair = keyPair; // Save the key to global variables.
1069    return signer.init(globalKeyPair.priKey);
1070  }).then(async () => {
1071    // If the plaintext is too large, split the plaintext based on the specified length and cyclically call update() to pass in the plaintext.
1072    for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1073      let tempStr = globalPlainText.substr(i * textSplitLen, textSplitLen);
1074      let tempBlob = { data : stringToUint8Array(tempStr) };
1075      await signer.update(tempBlob);
1076    }
1077    return signer.sign(null);
1078  }).then(data =>{
1079    globalSignData = data.data;
1080    console.info(`globalSignOutput len is ${globalSignData.length}, data is: ${globalSignData.toString()}`);
1081    return verifier.init(globalKeyPair.pubKey);
1082  }).then(async() => {
1083    // Split and decrypt the ciphertext by 128 bytes, and combine the plaintext obtained each time.
1084    for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1085      let tempData = globalPlainText.slice(i * textSplitLen, (i + 1) * textSplitLen);
1086      let tempBlob = { data : stringToUint8Array(tempData) };
1087      await verifier.update(tempBlob);
1088    }
1089    return verifier.verify(null, { data : globalSignData});
1090  }).then(res => {
1091    console.info(`verify res is ${res}`);
1092  }).catch(error => {
1093    console.error(`catch error, ${error.code}, ${error.message}`);
1094  })
1095}
1096```
1097
1098## Generating a Digest
1099
1100**When to Use**
1101
1102A message digest (MD) is a fixed size numeric representation of the content of a message, computed by a has function. It is sent with the message. The receiver can generate a digest for the message and compare it with the digest received. If the two digests are the same, the message integrity is verified.
1103
1104Typical MD operations involve the following:
1105
11061. Create an **Md** instance.
11072. Add one or more segments of data for generating a digest.
11083. Compute a digest.
11094. Obtain the algorithm and length of a digest.
1110
1111**Available APIs**
1112
1113For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
1114
1115| Instance         | API                                                      | Description                                              |
1116| --------------- | ------------------------------------------------------------ | -------------------------------------------------- |
1117| cryptoFramework | function createMd(algName : string) : Md;                    | Creates an **Md** instance.                  |
1118| Md              | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | Updates the data for a digest. This API uses an asynchronous callback to return the result.|
1119| Md              | update(input : DataBlob) : Promise\<void>;                  | Updates the data for a digest. This API uses a promise to return the result. |
1120| Md              | digest(callback : AsyncCallback\<DataBlob>) : void;         | Generates the digest. This API uses an asynchronous callback to return the result.                      |
1121| Md              | digest() : Promise\<DataBlob>;                              | Generates the digest. This API uses a promise to return the result.                       |
1122| Md              | getMdLength() : number;                                      | Obtains the digest length based on the specified digest algorithm.            |
1123| Md              | readonly algName : string;                                   | Obtains the digest algorithm.                          |
1124
1125**How to Develop**
1126
11271. Call **createMd()** to create an **Md** instance.
11282. Call **update()** to pass in the data for computing a digest. **update()** can be called multiple times to pass in the data by segment.
11293. Call **digest()** to compute a digest.
11304. Obtain the digest algorithm and length of the digest generated.
1131
1132```javascript
1133import cryptoFramework from "@ohos.security.cryptoFramework"
1134
1135// Convert string into uint8Arr.
1136function stringToUint8Array(str) {
1137  var arr = [];
1138  for (var i = 0, j = str.length; i < j; ++i) {
1139      arr.push(str.charCodeAt(i));
1140  }
1141  var tmpUint8Array = new Uint8Array(arr);
1142  return tmpUint8Array;
1143}
1144
1145// Generate a dataBlob of the given length.
1146function GenDataBlob(dataBlobLen) {
1147  var dataBlob;
1148  if (dataBlobLen == 12) {
1149      dataBlob = {data: stringToUint8Array("my test data")};
1150  } else {
1151      console.error("GenDataBlob: dataBlobLen is invalid");
1152      dataBlob = {data: stringToUint8Array("my test data")};
1153  }
1154  return dataBlob;
1155}
1156
1157// Compute an MD using promise-based APIs.
1158function doMdByPromise(algName) {
1159  var md;
1160  try {
1161    md = cryptoFramework.createMd(algName);
1162  } catch (error) {
1163    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1164  }
1165  console.error("[Promise]: Md algName is: " + md.algName);
1166  // Initial update().
1167  var promiseMdUpdate = md.update(GenDataBlob(12));
1168  promiseMdUpdate.then(() => {
1169    // Call update() multiple times based on service requirements.
1170    promiseMdUpdate = md.update(GenDataBlob(12));
1171    return promiseMdUpdate;
1172  }).then(mdOutput => {
1173    var PromiseMdDigest = md.digest();
1174    return PromiseMdDigest;
1175  }).then(mdOutput => {
1176    console.error("[Promise]: MD result: " + mdOutput.data);
1177    var mdLen = md.getMdLength();
1178    console.error("[Promise]: MD len: " + mdLen);
1179  }).catch(error => {
1180    console.error("[Promise]: error: " + error.message);
1181  });
1182}
1183
1184// Compute an MD using callback-based APIs.
1185function doMdByCallback(algName) {
1186  var md;
1187  try {
1188    md = cryptoFramework.createMd(algName);
1189  } catch (error) {
1190    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1191  }
1192  console.error("[Callback]: Md algName is: " + md.algName);
1193  // Initial update().
1194  md.update(GenDataBlob(12), (err,) => {
1195    if (err) {
1196      console.error("[Callback]: err: " + err.code);
1197    }
1198    // Call update() multiple times based on service requirements.
1199    md.update(GenDataBlob(12), (err1,) => {
1200      if (err1) {
1201        console.error("[Callback]: err: " + err1.code);
1202      }
1203      md.digest((err2, mdOutput) => {
1204        if (err2) {
1205          console.error("[Callback]: err: " + err2.code);
1206        } else {
1207          console.error("[Callback]: MD result: " + mdOutput.data);
1208          var mdLen = md.getMdLength();
1209          console.error("[Callback]: MD len: " + mdLen);
1210        }
1211      });
1212    });
1213  });
1214}
1215```
1216The following example demonstrates how to call **update()** multiple times to update the MD.
1217```javascript
1218import cryptoFramework from "@ohos.security.cryptoFramework"
1219
1220async function updateData(index, obj, data) {
1221  console.error("update " + (index + 1) + " MB data...");
1222  return obj.update(data);
1223}
1224
1225function stringToUint8Array(str) {
1226  var arr = [];
1227  for (var i = 0, j = str.length; i < j; ++i) {
1228    arr.push(str.charCodeAt(i));
1229  }
1230  var tmpUint8Array = new Uint8Array(arr);
1231  return tmpUint8Array;
1232}
1233
1234function GenDataBlob(dataBlobLen) {
1235  var dataBlob;
1236  if (dataBlobLen == 12) {
1237    dataBlob = {data: stringToUint8Array("my test data")};
1238  } else {
1239    console.error("GenDataBlob: dataBlobLen is invalid");
1240    dataBlob = {data: stringToUint8Array("my test data")};
1241  }
1242  return dataBlob;
1243}
1244
1245function LoopMdPromise(algName, loopSize) {
1246  var md;
1247  try {
1248    md = cryptoFramework.createMd(algName);
1249  } catch (error) {
1250    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1251    return;
1252  }
1253  console.error("[Promise]: Md algName is: " + md.algName);
1254  var promiseMdUpdate = md.update(GenDataBlob(12));
1255  promiseMdUpdate.then(() => {
1256    var PromiseMdDigest = md.digest();
1257    return PromiseMdDigest;
1258  }).then(async () => {
1259    for (var i = 0; i < loopSize; i++) {
1260      await updateData(i, md, GenDataBlob(12));
1261    }
1262    var PromiseMdDigest = md.digest();
1263    return PromiseMdDigest;
1264  }).then(mdOutput => {
1265    console.error("[Promise]: MD result: " + mdOutput.data);
1266    var mdLen = md.getMdLength();
1267    console.error("[Promise]: MD len: " + mdLen);
1268  }).catch(error => {
1269    console.error("[Promise]: error: " + error.message);
1270  });
1271}
1272```
1273
1274## Performing Key Agreement
1275
1276**When to Use**
1277
1278Key agreement allows two parties to establish a shared secret over an insecure channel.
1279
1280**Available APIs**
1281
1282For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
1283
1284|Instance|API|Description|
1285|---|---|---|
1286|cryptoFramework|createKeyAgreement(algName : string) : KeyAgreement|Creates a **KeyAgreement** instance.|
1287|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\<DataBlob>) : void|Generates a shared secret. This API uses an asynchronous callback to return the result.|
1288|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\<DataBlob>|Generates a shared secret. This API uses a promise to return the result.|
1289
1290**How to Develop**
1291
12921. Use **createKeyAgreement()** to create a **KeyAgreement** object for subsequent key agreement operations.
12932. Use **generateSecret()** provided by **KeyAgreement** to pass in the peer ECC public key object and the ECC private key object generated locally.
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## Generating a MAC
1341
1342**When to Use**
1343
1344A message authentication code (MAC) can be used to verify both the integrity and authenticity of a message using a shared secret.
1345
1346Typical MAC operations involve the following:
1347
13481. Create a **Mac** instance.
13492. Initialize the **Mac** instance, add one or more segments of data for generating a MAC, and generate a MAC.
13503. Obtain the algorithm and length of a MAC.
1351
1352**Available APIs**
1353
1354For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
1355
1356| Instance         | API                                                      | Description                                               |
1357| --------------- | ------------------------------------------------------------ | --------------------------------------------------- |
1358| cryptoFramework | function createMac(algName : string) : Mac;                  | Creates a **Mac** instance.                |
1359| Mac             | init(key : SymKey, callback : AsyncCallback\<void>) : void; | Initializes the MAC operation. This API uses an asynchronous callback to return the result.|
1360| Mac             | init(key : SymKey) : Promise\<void>;                        | Initializes the MAC operation. This API uses a promise to return the result. |
1361| Mac             | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | Updates the data for the MAC operation. This API uses an asynchronous callback to return the result.      |
1362| Mac             | update(input : DataBlob) : Promise\<void>;                  | Updates the data for the MAC operation. This API uses a promise to return the result.       |
1363| Mac             | doFinal(callback : AsyncCallback\<DataBlob>) : void;        | Finalizes the MAC operation to generate a MAC. This API uses an asynchronous callback to return the result.                |
1364| Mac             | doFinal() : Promise\<DataBlob>;                             | Finalizes the MAC operation to generate a MAC. This API uses a promise to return the result.                 |
1365| Mac             | getMacLength() : number;                                     | Obtains the length of the MAC based on the specified algorithm.              |
1366| Mac             | readonly algName : string;                                   | Obtains the digest algorithm.                           |
1367
1368**How to Develop**
1369
13701. Call **createMac()** to create a **Mac** instance.
13712. Call **init()** to initialize the **Mac** instance with the symmetric key passed in.
13723. Call **update()** one or more times to add the data for computing a MAC.
13734. Call **doFinal()** to generate a MAC.
13745. Obtain the algorithm and length of the MAC.
1375
1376```javascript
1377import cryptoFramework from "@ohos.security.cryptoFramework"
1378
1379// Convert string into uint8Arr.
1380function stringToUint8Array(str) {
1381  var arr = [];
1382  for (var i = 0, j = str.length; i < j; ++i) {
1383      arr.push(str.charCodeAt(i));
1384  }
1385  var tmpUint8Array = new Uint8Array(arr);
1386  return tmpUint8Array;
1387}
1388
1389// Generate a blob.
1390function GenDataBlob(dataBlobLen) {
1391  var dataBlob;
1392  if (dataBlobLen == 12) {
1393      dataBlob = {data: stringToUint8Array("my test data")};
1394  } else {
1395      console.error("GenDataBlob: dataBlobLen is invalid");
1396      dataBlob = {data: stringToUint8Array("my test data")};
1397  }
1398  return dataBlob;
1399}
1400
1401function doHmacByPromise(algName) {
1402  var mac;
1403  try {
1404    mac = cryptoFramework.createMac(algName);
1405  } catch (error) {
1406    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1407  }
1408  console.error("[Promise]: Mac algName is: " + mac.algName);
1409  var KeyBlob = {
1410    data : stringToUint8Array("12345678abcdefgh")
1411  }
1412  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1413  var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
1414  promiseConvertKey.then(symKey => {
1415    var promiseMacInit = mac.init(symKey);
1416    return promiseMacInit;
1417  }).then(() => {
1418    // Initial update().
1419    var promiseMacUpdate = mac.update(GenDataBlob(12));
1420    return promiseMacUpdate;
1421  }).then(() => {
1422    // Call update() multiple times based on service requirements.
1423    var promiseMacUpdate = mac.update(GenDataBlob(12));
1424    return promiseMacUpdate;
1425  }).then(() => {
1426    var PromiseMacDoFinal = mac.doFinal();
1427    return PromiseMacDoFinal;
1428  }).then(macOutput => {
1429    console.error("[Promise]: HMAC result: " + macOutput.data);
1430    var macLen = mac.getMacLength();
1431    console.error("[Promise]: MAC len: " + macLen);
1432  }).catch(error => {
1433    console.error("[Promise]: error: " + error.message);
1434  });
1435}
1436
1437// Generate a MAC using callback-based APIs.
1438function doHmacByCallback(algName) {
1439  var mac;
1440  try {
1441    mac = cryptoFramework.createMac(algName);
1442  } catch (error) {
1443    AlertDialog.show({message: "[Callback]: error code: " + error.code + ", message is: " + error.message});
1444    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1445  }
1446  var KeyBlob = {
1447    data : stringToUint8Array("12345678abcdefgh")
1448  }
1449  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1450  symKeyGenerator.convertKey(KeyBlob, (err, symKey) => {
1451    if (err) {
1452      console.error("[Callback]: err: " + err.code);
1453    }
1454    mac.init(symKey, (err1, ) => {
1455      if (err1) {
1456        console.error("[Callback]: err: " + err1.code);
1457      }
1458      // Initial update().
1459      mac.update(GenDataBlob(12), (err2, ) => {
1460        if (err2) {
1461          console.error("[Callback]: err: " + err2.code);
1462        }
1463        // Call update() multiple times based on service requirements.
1464        mac.update(GenDataBlob(12), (err3, ) => {
1465          if (err3) {
1466            console.error("[Callback]: err: " + err3.code);
1467          }
1468          mac.doFinal((err4, macOutput) => {
1469            if (err4) {
1470              console.error("[Callback]: err: " + err4.code);
1471            } else {
1472              console.error("[Callback]: HMAC result: " + macOutput.data);
1473              var macLen = mac.getMacLength();
1474              console.error("[Callback]: MAC len: " + macLen);
1475            }
1476          });
1477        });
1478      });
1479    });
1480  });
1481}
1482```
1483The following example demonstrates how to call **update()** multiple times to update the MAC.
1484```javascript
1485import cryptoFramework from "@ohos.security.cryptoFramework"
1486
1487async function updateData(index, obj, data) {
1488  console.error("update " + (index + 1) + " MB data...");
1489  return obj.update(data);
1490}
1491
1492function stringToUint8Array(str) {
1493  var arr = [];
1494  for (var i = 0, j = str.length; i < j; ++i) {
1495    arr.push(str.charCodeAt(i));
1496  }
1497  var tmpUint8Array = new Uint8Array(arr);
1498  return tmpUint8Array;
1499}
1500
1501function GenDataBlob(dataBlobLen) {
1502  var dataBlob;
1503  if (dataBlobLen == 12) {
1504    dataBlob = {data: stringToUint8Array("my test data")};
1505  } else {
1506    console.error("GenDataBlob: dataBlobLen is invalid");
1507    dataBlob = {data: stringToUint8Array("my test data")};
1508  }
1509  return dataBlob;
1510}
1511
1512function LoopHmacPromise(algName, loopSize) {
1513  var mac;
1514  try {
1515    mac = cryptoFramework.createMac(algName);
1516  } catch (error) {
1517    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1518    return;
1519  }
1520  console.error("[Promise]: Mac algName is: " + mac.algName);
1521  var KeyBlob = {
1522    data : stringToUint8Array("12345678abcdefgh")
1523  }
1524  var symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
1525  var promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
1526  promiseConvertKey.then(symKey => {
1527    var promiseMacInit = mac.init(symKey);
1528    return promiseMacInit;
1529  }).then(async () => {
1530    for (var i = 0; i < loopSize; i++) {
1531      await updateData(i, mac, GenDataBlob(12));
1532    }
1533    var promiseMacUpdate = mac.update(GenDataBlob(12));
1534    return promiseMacUpdate;
1535  }).then(() => {
1536    var PromiseMacDoFinal = mac.doFinal();
1537    return PromiseMacDoFinal;
1538  }).then(macOutput => {
1539    console.error("[Promise]: HMAC result: " + macOutput.data);
1540    var macLen = mac.getMacLength();
1541    console.error("[Promise]: MAC len: " + macLen);
1542  }).catch(error => {
1543    console.error("[Promise]: error: " + error.message);
1544  });
1545}
1546```
1547
1548
1549## Generating a Random Number
1550
1551**When to Use**
1552
1553Typical random number operations involve the following:
1554
1555- Generate a random number.
1556- Set a seed based on the random number generated.
1557
1558**Available APIs**
1559
1560For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
1561
1562| Instance         | API                                                      | Description                                          |
1563| --------------- | ------------------------------------------------------------ | ---------------------------------------------- |
1564| cryptoFramework | function createRandom() : Random;                            | Creates a **Random** instance.                          |
1565| Random          | generateRandom(len : number, callback: AsyncCallback\<DataBlob>) : void; | Generates a random number. This API uses an asynchronous callback to return the result.  |
1566| Random          | generateRandom(len : number) : Promise\<DataBlob>;          | Generates a random number. This API uses a promise to return the result.     |
1567| Random          | setSeed(seed : DataBlob) : void;                            | Sets a seed. |
1568
1569**How to Develop**
1570
15711. Call **createRandom()** to create a **Random** instance.
15722. Call **generateRandom()** to generate a random number of the given length.
15733. Call **setSeed()** to set a seed.
1574
1575```javascript
1576import cryptoFramework from "@ohos.security.cryptoFramework"
1577
1578// Generate a random number and set a seed using promise-based APIs.
1579function doRandByPromise(len) {
1580  var rand;
1581  try {
1582    rand = cryptoFramework.createRandom();
1583  } catch (error) {
1584    console.error("[Promise]: error code: " + error.code + ", message is: " + error.message);
1585  }
1586  var promiseGenerateRand = rand.generateRandom(len);
1587  promiseGenerateRand.then(randData => {
1588    console.error("[Promise]: rand result: " + randData.data);
1589      try {
1590          rand.setSeed(randData);
1591      } catch (error) {
1592          console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message);
1593      }
1594  }).catch(error => {
1595    console.error("[Promise]: error: " + error.message);
1596  });
1597}
1598
1599// Generate a random number and set a seed using callback-based APIs.
1600function doRandByCallback(len) {
1601  var rand;
1602  try {
1603    rand = cryptoFramework.createRandom();
1604  } catch (error) {
1605    console.error("[Callback]: error code: " + error.code + ", message is: " + error.message);
1606  }
1607  rand.generateRandom(len, (err, randData) => {
1608    if (err) {
1609      console.error("[Callback]: err: " + err.code);
1610    } else {
1611      console.error("[Callback]: generate random result: " + randData.data);
1612      try {
1613          rand.setSeed(randData);
1614      } catch (error) {
1615          console.log("setSeed failed, errCode: " + error.code + ", errMsg: " + error.message);
1616      }
1617    }
1618  });
1619}
1620```
1621