• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Crypto Framework Development
2
3> **NOTE**
4>
5> This guide applies only to JavaScript development using the SDK of API version 9 or later.
6
7## Key Generation and Conversion
8
9### When to Use
10
11Typical key generation operations involve the following:
12
131. Randomly create a key object for subsequent encryption and decryption.
142. Create a key object based on the specified key parameters for subsequent encryption and decryption.
153. Convert external or internal binary data into a key object for subsequent encryption and decryption.
164. Obtain the binary data of a key object for storage or transmission.
175. Obtain the parameter properties of an asymmetric key object for storage or transmission.
18
19> **NOTE**
20>
21> The key object can be a symmetric key object (**SymKey**) or an asymmetric key pair object (**KeyPair**). The **KeyPair** object consists a public key (**PubKey**) and a private key (**PriKey**). For details about the relationship between the keys, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
22
23### Available APIs
24
25The following table describes the APIs used in typical key generation operations. For more information about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
26
27
28|Instance|API|Description|
29|---|---|---|
30|cryptoFramework|createAsyKeyGenerator(algName : string) : AsyKeyGenerator|Creates an **AsyKeyGenerator** instance based on the asymmetric key pair specifications specified by **algName**.|
31|cryptoFramework|createAsyKeyGeneratorBySpec(asyKeySpec: AsyKeySpec): AsyKeyGeneratorBySpec;|Creates an **AsyKeyGenerator** instance based on the asymmetric key specifications specified by the key parameter.|
32|cryptoFramework|createSymKeyGenerator(algName : string) : SymKeyGenerator|Creates a **SymKeyGenerator** instance.|
33|AsyKeyGenerator|generateKeyPair(callback : AsyncCallback\<KeyPair>) : void|Generates an asymmetric key pair randomly. This API uses an asynchronous callback to return the result.|
34|AsyKeyGenerator|generateKeyPair() : Promise\<KeyPair>|Generates an asymmetric key pair randomly. This API uses a promise to return the result.|
35|SymKeyGenerator|generateSymKey(callback : AsyncCallback\<SymKey>) : void|Generates a symmetric key randomly. This API uses an asynchronous callback to return the result.|
36|SymKeyGenerator|generateSymKey() : Promise\<SymKey>|Generates a symmetric key randomly. This API uses a promise to return the result.|
37| 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.)|
38| 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.)|
39| 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.|
40| SymKeyGenerator         |convertKey(pubKey : DataBlob, priKey : DataBlob) : Promise\<KeyPair>| Converts binary data into a symmetric key. This API uses a promise to return the result.|
41| Key | getEncoded() : DataBlob;  | Obtains the binary data of a key. (The child class instances of **Key** include **SymKey**, **PubKey**, and **PriKey**.)|
42
43### Randomly Generating an RSA Key Pair and Obtaining the Binary Data
44
45Randomly generate an asymmetric key pair and obtain its binary data.
46
471. Create an **AsyKeyGenerator** instance.
482. Randomly generate an asymmetric key pair using **AsyKeyGenerator**.
493. Obtain the binary data of the key pair generated.
50
51Example: Randomly generate an RSA key (1024 bits and two primes) in promise mode.
52
53```ts
54import cryptoFramework from '@ohos.security.cryptoFramework';
55import { BusinessError } from '@ohos.base';
56
57function generateAsyKey() {
58  // Create an AsyKeyGenerator instance.
59  let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
60  // Use the key generator to randomly generate an asymmetric key pair.
61  let keyGenPromise = rsaGenerator.generateKeyPair();
62  keyGenPromise.then(keyPair => {
63    let pubKey = keyPair.pubKey;
64    let priKey = keyPair.priKey;
65    // Obtain the binary data of the asymmetric key pair.
66    let pkBlob = pubKey.getEncoded();
67    let skBlob = priKey.getEncoded();
68    AlertDialog.show({ message: 'pk bin data' + pkBlob.data });
69    AlertDialog.show({ message: 'sk bin data' + skBlob.data });
70  })
71}
72```
73
74### Randomly Generating an AES Key and Obtaining the Binary Data
75
76Randomly generate a symmetric key and obtain its binary data.
77
781. Create a **SymKeyGenerator** instance.
792. Randomly generate a symmetric key using **SymKeyGenerator**.
803. Obtain the binary data of the key generated.
81
82Example: Randomly generate an AES key (256 bits) in promise mode.
83
84```ts
85import cryptoFramework from '@ohos.security.cryptoFramework';
86import { BusinessError } from '@ohos.base';
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 the 256-bit key. The length is 32 bytes.
95    let encodedKey = key.getEncoded();
96    console.info('key hex:' + encodedKey.data);
97  })
98}
99```
100
101### Converting Binary Data into an RSA Key Pair
102
103Generate an RSA asymmetric key pair from the binary data.
104
1051. 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.
1062. Create an **AsyKeyGenerator** instance, and use **convertKey()** to convert the key binary data (data of the private or public key, or both) into a **KeyPair** instance.
107
108```ts
109import cryptoFramework from '@ohos.security.cryptoFramework';
110import { BusinessError } from '@ohos.base';
111
112function convertAsyKey() {
113  let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024');
114  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]);
115  let pkBlob: cryptoFramework.DataBlob = { data: pkVal };
116  rsaGenerator.convertKey(pkBlob, null, (err, keyPair) => {
117    if (err) {
118      AlertDialog.show({ message: 'Convert keyPair fail' });
119      return;
120    }
121    AlertDialog.show({ message: 'Convert keyPair success' });
122  })
123}
124```
125
126> **NOTE**
127>
128> The public key binary data to be converted by **convertKey()** must be in the DER format complying with X.509 specifications, and the private key binary data must be in the DER format complying with PKCS #8 specifications.
129
130### Converting Binary Data into an ECC Key Pair
131
132Generate an ECC asymmetric key pair from the binary data.
133
1341. Obtain the ECC binary key data and encapsulate it into a **DataBlob** instance.
1352. Use **convertKey()** to convert the binary data (data of the private or public key, or both) into a **KeyPair** instance.
136
137```ts
138import cryptoFramework from '@ohos.security.cryptoFramework';
139import { BusinessError } from '@ohos.base';
140
141function convertEccAsyKey() {
142  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]);
143  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]);
144  let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyArray };
145  let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyArray };
146  let generator = cryptoFramework.createAsyKeyGenerator('ECC256');
147  generator.convertKey(pubKeyBlob, priKeyBlob, (error, data) => {
148    if (error) {
149      AlertDialog.show({ message: 'Convert keyPair fail' });
150      return;
151    }
152    AlertDialog.show({ message: 'Convert keyPair success' });
153  })
154}
155```
156
157### Converting Binary Data into a 3DES Key
158
159Generate a symmetric key from the binary key data.
160
1611. Create a **SymKeyGenerator** instance.
1622. Convert the binary data into a **SymKey** instance.
1633. Obtain the binary data of the key instance generated.
164
165Example: Generate a 3DES key (192 bits only) in callback mode.
166
167```ts
168import cryptoFramework from '@ohos.security.cryptoFramework';
169import { BusinessError } from '@ohos.base';
170
171function genKeyMaterialBlob(): cryptoFramework.DataBlob {
172  let arr = [
173    0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56,
174    0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c,
175    0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes)
176  let keyMaterial = new Uint8Array(arr);
177  return { data: keyMaterial };
178}
179
180function testConvertSymKey() {
181  // Create a SymKeyGenerator instance.
182  let symKeyGenerator = cryptoFramework.createSymKeyGenerator('3DES192');
183  // Generate a symmetric key based on the specified data.
184  let keyMaterialBlob = genKeyMaterialBlob();
185  try {
186    symKeyGenerator.convertKey(keyMaterialBlob, (error, key) => {
187      if (error) { // If the service logic fails to be executed, the first parameter of callback returns error information, that is, an exception is thrown asynchronously.
188        let e: BusinessError = error as BusinessError;
189        console.error(`convertKey error, ${e.code}, ${e.message}`);
190        return;
191      }
192      console.info(`key algName: ${key.algName}`);
193      console.info(`key format: ${key.format}`);
194      let encodedKey = key.getEncoded(); // Obtain the binary data of the symmetric key and output in bytes array. The length is 24 bytes.
195      console.info('key getEncoded hex: ' + encodedKey.data);
196    })
197  } catch (error) { // Throw an exception immediately when an error is detected in parameter check.
198    let e: BusinessError = error as BusinessError;
199    console.error(`convertKey failed, ${e.code}, ${e.message}`);
200    return;
201  }
202}
203```
204
205### Randomly Generating an SM2 Key Pair and Obtaining the Binary Data
206
207> **NOTE**
208>
209> SM2 asymmetric keys can be randomly generated from API version 10.
210
211Randomly generate an asymmetric key pair and obtain its binary data.
212
2131. Create an **AsyKeyGenerator** instance.
2142. Randomly generate an asymmetric key pair using **AsyKeyGenerator**.
2153. Obtain the binary data of the key pair generated.
216
217Example: Randomly generate an SM2 key (256 bits) in promise mode.
218
219```ts
220import cryptoFramework from '@ohos.security.cryptoFramework';
221import { BusinessError } from '@ohos.base';
222
223function generateSM2Key() {
224  // Create an AsyKeyGenerator instance.
225  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
226  // Use the key generator to randomly generate an asymmetric key pair.
227  let keyGenPromise = sm2Generator.generateKeyPair();
228  keyGenPromise.then(keyPair => {
229    let pubKey = keyPair.pubKey;
230    let priKey = keyPair.priKey;
231    // Obtain the binary data of the asymmetric key pair.
232    let pkBlob = pubKey.getEncoded();
233    let skBlob = priKey.getEncoded();
234    AlertDialog.show({ message: "pk bin data" + pkBlob.data });
235    AlertDialog.show({ message: "sk bin data" + skBlob.data });
236  })
237}
238```
239
240### Randomly Generating an SM4 Key and Obtaining the Binary Data
241
242 > **NOTE**
243 >
244 > SM4 keys can be randomly generated from API version 10.
245
246Randomly generate a symmetric key and obtain its binary data.
247
2481. Create a **SymKeyGenerator** instance.
2492. Randomly generate a symmetric key using **SymKeyGenerator**.
2503. Obtain the binary data of the key generated.
251
252Example: Randomly generate an SM4 key (128 bits) in promise mode.
253
254```ts
255import cryptoFramework from '@ohos.security.cryptoFramework';
256import { BusinessError } from '@ohos.base';
257
258function testGenerateSM4Key() {
259  // Create a SymKeyGenerator instance.
260  let symKeyGenerator = cryptoFramework.createSymKeyGenerator("SM4_128");
261  // Use the key generator to randomly generate a symmetric key.
262  let promiseSymKey = symKeyGenerator.generateSymKey();
263  promiseSymKey.then(key => {
264    // Obtain the binary data of the symmetric key and output a 128-bit byte stream. The length is 16 bytes.
265    let encodedKey = key.getEncoded();
266    console.info('key hex:' + encodedKey.data);
267  })
268}
269```
270
271### Converting Binary Data into an SM2 Key Pair
272
273 > **NOTE**
274 >
275 > SM2 key conversion is supported from API version 10.
276
277Generate an SM2 asymmetric key pair from the given binary key data.
278
2791. Obtain the SM2 binary key data and encapsulate it into a **DataBlob** instance.
2802. Call **convertKey()** to convert the binary data (data of the private or public key, or both) into a **KeyPair** instance.
281
282```ts
283import cryptoFramework from '@ohos.security.cryptoFramework';
284import { BusinessError } from '@ohos.base';
285
286function convertSM2AsyKey() {
287  let pubKeyArray = new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 129, 28, 207, 85, 1, 130, 45, 3, 66, 0, 4, 90, 3, 58, 157, 190, 248, 76, 7, 132, 200, 151, 208, 112, 230, 96, 140, 90, 238, 211, 155, 128, 109, 248, 40, 83, 214, 78, 42, 104, 106, 55, 148, 249, 35, 61, 32, 221, 135, 143, 100, 45, 97, 194, 176, 52, 73, 136, 174, 40, 70, 70, 34, 103, 103, 161, 99, 27, 187, 13, 187, 109, 244, 13, 7]);
288  let priKeyArray = new Uint8Array([48, 49, 2, 1, 1, 4, 32, 54, 41, 239, 240, 63, 188, 134, 113, 31, 102, 149, 203, 245, 89, 15, 15, 47, 202, 170, 60, 38, 154, 28, 169, 189, 100, 251, 76, 112, 223, 156, 159, 160, 10, 6, 8, 42, 129, 28, 207, 85, 1, 130, 45]);
289  let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyArray };
290  let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyArray };
291  let generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
292  generator.convertKey(pubKeyBlob, priKeyBlob, (error, data) => {
293    if (error) {
294      AlertDialog.show({ message: "Convert keypair fail" });
295      return;
296    }
297    AlertDialog.show({ message: "Convert KeyPair success" });
298  })
299}
300```
301
302## Generating an Asymmetric Key Object and Obtaining Key Parameters
303
304### When to Use
305
306Typical key generation operations involve the following:
3071. Create a key object based on the specified asymmetric key parameters for subsequent encryption and decryption.
3082. Obtain the parameter properties of an asymmetric key object for storage or transmission.
309
310> **NOTE**
311>
312> - Key parameters can be used to generate asymmetric keys from API version 10.
313> - Asymmetric systems use a public key (**PubKey**) to encrypt data and a related private key (**PriKey**) to decrypt it. The public key and private key form a key pair (**KeyPair**). For details about asymmetric key parameters, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
314
315### Available APIs
316
317The following table describes the APIs used in typical key generation operations. For more information about the APIs, see [AsyKeyGeneratorBySpec](../reference/apis/js-apis-cryptoFramework.md#asykeygeneratorbyspec10).
318
319|Instance|API|Description|
320|---|---|---|
321|AsyKeyGeneratorBySpec|generateKeyPair(callback: AsyncCallback\<KeyPair>): void;|Generates a **KeyPair** instance based on the key parameters. This API uses an asynchronous callback to return the result.|
322|AsyKeyGeneratorBySpec|generateKeyPair(): Promise\<KeyPair>;|Generates a **KeyPair** instance based on the key parameters. This API uses a promise to return the result.|
323|AsyKeyGeneratorBySpec|generatePriKey(callback: AsyncCallback\<KeyPair>): void;|Generates a **PriKey** instance based on the key parameters. This API uses an asynchronous callback to return the result.|
324|AsyKeyGeneratorBySpec|generatePriKey(): Promise\<KeyPair>;|Generates a **PriKey** instance based on the key parameters. This API uses a promise to return the result.|
325|AsyKeyGeneratorBySpec|generatePubKey(callback: AsyncCallback\<KeyPair>): void;|Generates a **PubKey** instance based on the key parameters. This API uses an asynchronous callback to return the result.|
326|AsyKeyGeneratorBySpec|generatePubKey(): Promise\<KeyPair>;|Generates a **PubKey** instance based on the key parameters. This API uses a promise to return the result.|
327| PriKey | getAsyKeySpec(itemType: AsyKeySpecItem): bigint \| string \| number;  | Obtains the key specifications of a **PriKey** instance.|
328| PubKey | getAsyKeySpec(itemType: AsyKeySpecItem): bigint \| string \| number;  | Obtains the key specifications of a **PubKey** instance.|
329
330### Generating an ECC Key Pair and Obtaining Key Specifications
331
332Generate an ECC key pair based on parameters and obtain the key specifications.
333
3341. Create an **AsyKeyGenerator** based on key parameters.
3352. Use the **AsyKeyGenerator** to generate an asymmetric key pair based on the specified key parameters.
3363. Obtain the key specifications of a key object.
337
338Example: Generate an ECC key based on key parameters in promise mode.
339
340```ts
341import cryptoFramework from '@ohos.security.cryptoFramework';
342import { BusinessError } from '@ohos.base';
343
344// Print bigint information.
345function showBigIntInfo(bnName: string, bnValue: bigint | string | number) {
346  if (typeof bnValue === 'string') {
347    console.error('type is string');
348    return;
349  }
350  if (typeof bnValue === 'number') {
351    console.error('type is number');
352    return;
353  }
354  console.info(bnName + ":");
355  console.info(". Decimal: " + bnValue.toString());
356  console.info(". Hexadecimal: " + bnValue.toString(16));
357  console.info(". Length (bits): " + bnValue.toString(2).length);
358}
359
360// Construct the EccCommonSpec struct based on the key specifications. The EccCommonSpec struct defines the common parameters of the ECC private key and public key.
361function genEccCommonSpec(): cryptoFramework.ECCCommonParamsSpec {
362  let fieldFp: cryptoFramework.ECFieldFp = {
363    fieldType: "Fp",
364    p: BigInt("0xffffffffffffffffffffffffffffffff000000000000000000000001")
365  }
366
367  let G: cryptoFramework.Point = {
368    x: BigInt("0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21"),
369    y: BigInt("0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34")
370  }
371
372  let eccCommonSpec: cryptoFramework.ECCCommonParamsSpec = {
373    algName: "ECC",
374    specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC,
375    field: fieldFp,
376    a: BigInt("0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe"),
377    b: BigInt("0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4"),
378    g: G,
379    n: BigInt("0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d"),
380    h: 1
381  }
382  return eccCommonSpec;
383}
384
385// Print the ECC key specifications.
386function showEccSpecDetailInfo(key: cryptoFramework.PubKey | cryptoFramework.PriKey, keyType: string) {
387  console.info("show detail of " + keyType + ":");
388  try {
389    let p = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FP_P_BN);
390    showBigIntInfo("--- p", p); // length is 224, hex : ffffffffffffffffffffffffffffffff000000000000000000000001
391
392    let a = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_A_BN);
393    showBigIntInfo("--- a", a); // length is 224, hex : fffffffffffffffffffffffffffffffefffffffffffffffffffffffe
394
395    let b = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_B_BN);
396    showBigIntInfo("--- b", b); // length is 224, hex : b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
397
398    let gX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_X_BN);
399    showBigIntInfo("--- gX", gX); // length is 224, hex : b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
400
401    let gY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_G_Y_BN);
402    showBigIntInfo("--- gY", gY); // length is 224, hex : bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34
403
404    let n = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_N_BN);
405    showBigIntInfo("--- n", n); // length is 224, hex : ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d
406
407    let h = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_H_NUM);
408    console.warn("--- h: " + h); // key h: 1
409
410    let fieldType = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_TYPE_STR);
411    console.warn("--- field type: " + fieldType); // key field type: Fp
412
413    let fieldSize = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_FIELD_SIZE_NUM);
414    console.warn("--- field size: " + fieldSize); // key field size: 224
415
416    let curveName = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_CURVE_NAME_STR);
417    console.warn("--- curve name: " + curveName); // key curve name: NID_secp224r1
418
419    if (keyType == "priKey") {
420      let sk = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_SK_BN);
421      showBigIntInfo("--- sk", sk);
422    } else if (keyType == "pubKey") {
423      let pkX = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_X_BN);
424      showBigIntInfo("--- pkX", pkX);
425      let pkY = key.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.ECC_PK_Y_BN);
426      showBigIntInfo("--- pkY", pkY);
427    }
428  } catch (error) {
429    console.error("getAsyKeySpec error");
430    let e: BusinessError = error as BusinessError;
431    console.error(`getAsyKeySpec failed, ${e.code}, ${e.message}`);
432  }
433}
434
435// Generate an ECC key pair based on the EccCommonSpec instance and obtain the key specifications.
436function testEccUseCommKeySpecGet() {
437  try {
438    let commKeySpec = genEccCommonSpec(); // Construct the EccCommonSpec object.
439    let generatorBySpec = cryptoFramework.createAsyKeyGeneratorBySpec(commKeySpec); // Create an AsyKeyGenerator instance based on the EccCommonSpec object.
440    let keyPairPromise = generatorBySpec.generateKeyPair(); // Generate an ECC key pair.
441    keyPairPromise.then(keyPair => {
442      showEccSpecDetailInfo(keyPair.priKey, "priKey"); // Obtain the ECC specifications of the private key.
443      showEccSpecDetailInfo(keyPair.pubKey, "pubKey"); // Obtain the ECC specifications of the public key.
444    }).catch((error: BusinessError) => {
445      // Capture exceptions such as logic errors asynchronously here.
446      console.error("generateComm error");
447      console.error("error code: " + error.code + ", message is: " + error.message);
448    })
449  } catch (error) {
450    // Capture parameter errors synchronously here.
451    console.error("testEccUseCommSpec error");
452    let e: BusinessError = error as BusinessError;
453    console.error(`ecc comm spec failed, ${e.code}, ${e.message}`);
454  }
455}
456```
457
458### Generating an RSA Public Key and Obtaining Key Specifications
459
460Generate an RSA public key based on parameters and obtain key specifications.
461
4621. Create an **AsyKeyGenerator** based on key parameters.
4632. Use the **AsyKeyGenerator** to generate the public key of an asymmetric key pair.
4643. Obtain the key specifications of the public key object.
465
466Example: Generate an RSA public key based on key parameters in callback mode.
467```ts
468import cryptoFramework from '@ohos.security.cryptoFramework';
469import { BusinessError } from '@ohos.base';
470// Generate RSA public key specifications.
471function genRsaPubKeySpec(nIn: bigint, eIn: bigint): cryptoFramework.RSAPubKeySpec {
472  let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
473    n: nIn,
474    algName: "RSA",
475    specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
476  };
477  let rsaPubKeySpec: cryptoFramework.RSAPubKeySpec = {
478    params: rsaCommSpec,
479    pk: eIn,
480    algName: "RSA",
481    specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC
482  };
483  return rsaPubKeySpec;
484}
485
486// Construct an RSA public key specifications object based on the key parameters.
487function genRsa2048PubKeySpec() {
488  let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
489  let eIn = BigInt("0x010001");
490  return genRsaPubKeySpec(nIn, eIn);
491}
492
493// Compare the RSA public key specifications with the expected values.
494function compareRsaPubKeyBySpec(rsaKeySpec: cryptoFramework.RSAPubKeySpec, n: bigint | string | number, e: bigint | string | number) {
495  if (typeof n === 'string' || typeof e === 'string') {
496    console.error('type is string');
497    return false;
498  }
499  if (typeof n === 'number' || typeof e === 'number') {
500    console.error('type is number');
501    return false;
502  }
503  if (rsaKeySpec.params.n != n) {
504    return false;
505  }
506  if (rsaKeySpec.pk != e) {
507    return false;
508  }
509  return true;
510}
511
512// Generate an RSA public key based on the RSA public key specifications, obtain the key specifications, and compare the key specifications with the expected values.
513function rsaUsePubKeySpecGetCallback() {
514  let rsaPubKeySpec = genRsa2048PubKeySpec();
515  let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaPubKeySpec);
516  rsaGeneratorSpec.generatePubKey((error, key) => {
517    let pubKey = key;
518    let nBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_N_BN);
519    let eBN = pubKey.getAsyKeySpec(cryptoFramework.AsyKeySpecItem.RSA_PK_BN);
520    if (compareRsaPubKeyBySpec(rsaPubKeySpec, nBN, eBN) != true) {
521      AlertDialog.show({ message: "error pub key big number" });
522    } else {
523      console.info("n, e in the pubKey are same as the spec.");
524    }
525    if (error) {
526      console.error("generate pubKey error" + "error code: " + error.code + "error message" + error.message);
527    }
528  });
529}
530```
531
532## Encryption and Decryption
533
534### When to Use
535
536Important data needs to be encrypted in data storage or transmission for security purposes. Typical encryption and decryption operations involve the following:
5371. Encrypt and decrypt data using a symmetric key.
5382. Encrypt and decrypt data using an asymmetric key pair.
5393. Obtain and set the **CipherSpecItem** parameter when the PKCS1_OAEP padding mode is used in RSA.
540
541> **NOTE**
542>
543> - From API version 10, [CipherSpecItem](../reference/apis/js-apis-cryptoFramework.md#cipherspecitem10) can be obtained and set when the PKCS1_OAEP padding mode is used in RSA.
544> - From API version 10, the string parameter without the key length is supported in encryption and decryption.
545
546### Available APIs
547
548The following table describes the APIs used in the typical encryption and decryption operations. For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
549> **NOTE**
550>
551> Due to complexity of cryptographic algorithms, the implementation varies depending on the key specifications and parameters you use, and cannot be enumerated by sample code. Before you start, understand the APIs to ensure correct use of these APIs.
552
553
554
555|Instance|API|Description|
556|---|---|---|
557|cryptoFramework|createCipher(transformation : string) : Cipher|Creates a **Cipher** instance.|
558|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.|
559|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.|
560|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.|
561|Cipher|update(data : DataBlob) : Promise\<DataBlob>|Updates the data for encryption and decryption. This API uses a promise to return the result.|
562|Cipher|doFinal(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Finalizes the encryption or decryption. This API uses an asynchronous callback to return the result.|
563|Cipher|doFinal(data : DataBlob) : Promise\<DataBlob>|Finalizes the encryption or decryption. This API uses a promise to return the result.|
564|Cipher|getCipherSpec(itemType: CipherSpecItem): string \| Uint8Array|Obtains cipher specifications. Currently, only the RSA is supported.|
565|Cipher|setCipherSpec(itemType: CipherSpecItem, itemValue: Uint8Array): void|Sets cipher specifications. Currently, only the RSA is supported.|
566
567### Encrypting and Decrypting Data Using AES GCM (Promise)
568
569Encrypt and decrypt data using an AES symmetric key.
570
5711. Create a **SymKeyGenerator** instance.
5722. Use the **SymKeyGenerator** to randomly generate a symmetric key.
5733. Create a **Cipher** instance.
5744. Encrypt or decrypt data.
575
576```ts
577import cryptoFramework from '@ohos.security.cryptoFramework';
578import { BusinessError } from '@ohos.base';
579
580function genGcmParamsSpec() {
581  let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
582  let dataIv = new Uint8Array(arr);
583  let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
584
585  arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes
586  let dataAad = new Uint8Array(arr);
587  let aadBlob: cryptoFramework.DataBlob = { data: dataAad };
588
589  arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
590  let dataTag = new Uint8Array(arr);
591  let tagBlob: cryptoFramework.DataBlob = {
592    data: dataTag
593  }; // The GCM authTag is obtained by doFinal() in encryption and passed in params of init() in decryption.
594
595  let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {
596    iv: ivBlob,
597    aad: aadBlob,
598    authTag: tagBlob,
599    algName: "GcmParamsSpec"
600  };
601  return gcmParamsSpec;
602}
603
604// Convert strings in plaintext into byte streams.
605function stringToUint8Array(str: string) {
606  let arr = new Uint8Array(str.length);
607  for (let i = 0, j = str.length; i < j; ++i) {
608    arr[i] = str.charCodeAt(i);
609  }
610  return arr;
611}
612
613// Convert byte streams into strings in plaintext.
614function uint8ArrayToString(array: Uint8Array) {
615  let arrayString = '';
616  for (let i = 0; i < array.length; i++) {
617    arrayString += String.fromCharCode(array[i]);
618  }
619  return arrayString;
620}
621
622// Automatically generate an AES GCM key in promise mode.
623function testAesGcm() {
624  let symAlgName = 'AES128';
625  let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
626  console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
627  // Generate GCM parameter specifications.
628  let globalGcmParams = genGcmParamsSpec();
629  // Create a Cipher instance.
630  let cipherAlgName = 'AES128|GCM|PKCS7';
631  let globalCipher = cryptoFramework.createCipher(cipherAlgName);
632  console.info(`cipher algName: ${globalCipher.algName}`);
633  // Use the key generator to randomly generate a 128-bit symmetric key.
634  let globalCipherText: cryptoFramework.DataBlob;
635  let globalKey: cryptoFramework.SymKey;
636  let promiseSymKey = symKeyGenerator.generateSymKey();
637  promiseSymKey.then(key => {
638    // Initialize the Cipher instance and start encryption.
639    globalKey = key;
640    let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
641    return globalCipher.init(mode, globalKey, globalGcmParams);
642  })
643    .then(() => {
644      let plainText: cryptoFramework.DataBlob = { data: stringToUint8Array('this is test!') };
645      return globalCipher.update(plainText);
646    })
647    .then((updateOutput: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> => {
648      globalCipherText = updateOutput;
649      return globalCipher.doFinal(null);
650    })
651    .then(tag => {
652      // In GCM mode, the encrypted authentication information needs to be obtained from the output of doFinal() and passed in globalGcmParams of init() in decryption.
653      globalGcmParams.authTag = tag;
654      return;
655    })
656    .then(() => {
657      // Initialize the Cipher instance and start decryption.
658      let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
659      return globalCipher.init(mode, globalKey, globalGcmParams);
660    })
661    .then(() => {
662      return globalCipher.update(globalCipherText); // update
663    })
664    .then((updateOutput: cryptoFramework.DataBlob): Promise<cryptoFramework.DataBlob> => {
665      console.info('decrypt plainText: ' + uint8ArrayToString(updateOutput.data));
666      return globalCipher.doFinal(null);
667    })
668    .then(finalOutput => {
669      if (finalOutput == null) { // Check whether the result is null before using finalOutput.data.
670        console.info('GCM finalOutput is null');
671      }
672    })
673    .catch((error: BusinessError) => {
674      console.error(`catch error, ${error.code}, ${error.message}`);
675    })
676}
677```
678
679### Encrypting and Decrypting Data Using a 3DES ECB Symmetric Key (Callback)
680
681Encrypt and decrypt data using a 3DES symmetric key.
682
6831. Create a **SymKeyGenerator** instance.
6842. Generate a key based on the existing binary data.
6853. Create a **Cipher** instance.
6864. Encrypt or decrypt data.
687
688```ts
689import cryptoFramework from '@ohos.security.cryptoFramework';
690import { BusinessError } from '@ohos.base';
691
692// Convert strings in plaintext into byte streams.
693function stringToUint8Array(str: string) {
694  let arr = new Uint8Array(str.length);
695  for (let i = 0, j = str.length; i < j; ++i) {
696    arr[i] = str.charCodeAt(i);
697  }
698  return arr;
699}
700
701// Convert byte streams into strings in plaintext.
702function uint8ArrayToString(array: Uint8Array) {
703  let arrayString = '';
704  for (let i = 0; i < array.length; i++) {
705    arrayString += String.fromCharCode(array[i]);
706  }
707  return arrayString;
708}
709
710function genKeyMaterialBlob(): cryptoFramework.DataBlob {
711  let arr = [
712    0xba, 0x3d, 0xc2, 0x71, 0x21, 0x1e, 0x30, 0x56,
713    0xad, 0x47, 0xfc, 0x5a, 0x46, 0x39, 0xee, 0x7c,
714    0xba, 0x3b, 0xc2, 0x71, 0xab, 0xa0, 0x30, 0x72]; // keyLen = 192 (24 bytes)
715  let keyMaterial = new Uint8Array(arr);
716  return { data: keyMaterial };
717}
718
719// Generate a 3DES ECB key from the existing data in callback mode.
720function test3DesEcb() {
721  // Create a SymKeyGenerator instance.
722  let symAlgName = '3DES192';
723  let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
724  if (symKeyGenerator == null) {
725    console.error('createSymKeyGenerator failed');
726    return;
727  }
728  console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
729
730  // Create a Cipher instance.
731  let cipherAlgName = '3DES192|ECB|PKCS7';
732  let globalCipher = cryptoFramework.createCipher(cipherAlgName);
733
734  // Generate a symmetric key based on the specified data.
735  let keyMaterialBlob = genKeyMaterialBlob();
736  try {
737    symKeyGenerator.convertKey(keyMaterialBlob, (error, key) => {
738      if (error) {
739        console.error(`convertKey error, ${error.code}, ${error.message}`);
740        return;
741      }
742      console.info(`key algName: ${key.algName}`);
743      console.info(`key format: ${key.format}`);
744      let encodedKey = key.getEncoded();
745      console.info('key getEncoded: ' + encodedKey.data);
746      let globalKey = key;
747
748      // Initialize the Cipher instance and start encryption.
749      let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
750      // init
751      globalCipher.init(mode, key, null, (err,) => {
752        let plainText: cryptoFramework.DataBlob = { data: stringToUint8Array('this is test!') };
753        // update
754        globalCipher.update(plainText, (err, updateOutput) => {
755          let globalCipherText = updateOutput;
756          //doFinal
757          globalCipher.doFinal(null, (err, finalOutput) => {
758            if (err) {
759              console.error(`doFinal error, ${err.code}, ${err.message}`);
760              return;
761            }
762            if (finalOutput != null) {
763              let tmpCipherText = Array.from(globalCipherText.data);
764              let tmpFinalOutput = Array.from(finalOutput.data);
765              tmpCipherText = tmpCipherText.concat(tmpFinalOutput);
766              globalCipherText = { data: new Uint8Array(tmpCipherText) };
767            }
768            // Initialize the Cipher instance and start decryption.
769            let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
770            // init
771            globalCipher.init(mode, globalKey, null, (err,) => {
772              // update
773              globalCipher.update(globalCipherText, (err, updateOutput) => {
774                console.info('decrypt plainText: ' + uint8ArrayToString(updateOutput.data));
775                // doFinal
776                globalCipher.doFinal(null, (error, finalOutput) => {
777                  if (finalOutput != null) { // Check whether the result is null before using finalOutput.data.
778                    console.info('decrypt plainText: ' + uint8ArrayToString(finalOutput.data));
779                  }
780                })
781              })
782            })
783          })
784        })
785      })
786    })
787  } catch (error) {
788    let e: BusinessError = error as BusinessError;
789    console.error(`3des failed, ${e.code}, ${e.message}`);
790    return;
791  }
792}
793```
794
795### Encrypting and Decrypting Data Using an AES GCM Symmetric Key by Segment (Promise)
796
797Use an AES symmetric key to encrypt and decrypt a large amount of data by segment using **update()**.
798
7991. Create a **SymKeyGenerator** instance.
8002. Generate a key based on the existing binary data.
8013. Create a **Cipher** instance.
8024. Encrypt or decrypt data.
803
804Example: Encrypt and decrypt a large amount in AES GCM mode by calling **update()** multiple times in promise mode.
805
806```ts
807import cryptoFramework from '@ohos.security.cryptoFramework';
808import { BusinessError } from '@ohos.base';
809
810function genGcmParamsSpec() {
811  let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
812  let dataIv = new Uint8Array(arr);
813  let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
814
815  arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes
816  let dataAad = new Uint8Array(arr);
817  let aadBlob: cryptoFramework.DataBlob = { data: dataAad };
818
819  arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
820  let dataTag = new Uint8Array(arr);
821  let tagBlob: cryptoFramework.DataBlob = {
822    data: dataTag
823  }; // The GCM authTag is obtained by doFinal() in encryption and passed in params of init() in decryption.
824
825  let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {
826    iv: ivBlob,
827    aad: aadBlob,
828    authTag: tagBlob,
829    algName: "GcmParamsSpec"
830  };
831  return gcmParamsSpec;
832}
833
834// Convert strings in plaintext into byte streams.
835function stringToUint8Array(str: string) {
836  let arr = new Uint8Array(str.length);
837  for (let i = 0, j = str.length; i < j; ++i) {
838    arr[i] = str.charCodeAt(i);
839  }
840  return arr;
841}
842
843// Convert byte streams into strings in plaintext.
844function uint8ArrayToString(array: Uint8Array) {
845  let arrayString = '';
846  for (let i = 0; i < array.length; i++) {
847    arrayString += String.fromCharCode(array[i]);
848  }
849  return arrayString;
850}
851
852function testAesMultiUpdate() {
853  let symAlgName = 'AES128';
854  let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
855  console.info(`symKeyGenerator algName: ${symKeyGenerator.algName}`);
856  // Generate GCM parameter specifications.
857  let globalGcmParams = genGcmParamsSpec();
858  // Create a Cipher instance.
859  let cipherAlgName = 'AES128|GCM|PKCS7';
860  let globalCipher = cryptoFramework.createCipher(cipherAlgName);
861  console.info(`cipher algName: ${globalCipher.algName}`);
862  // Use the key generator to randomly generate a 128-bit symmetric key.
863  let globalCipherText: cryptoFramework.DataBlob;
864  let globalKey: cryptoFramework.SymKey;
865  let globalPlainText = '';
866  let promiseSymKey = symKeyGenerator.generateSymKey();
867  promiseSymKey.then(key => {
868    // Initialize the Cipher instance and start encryption.
869    globalKey = key;
870    let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
871    return globalCipher.init(mode, globalKey, globalGcmParams);
872  })
873    .then(async () => {
874      let plainText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; // Assume that the plaintext is of 43 bytes.
875      let messageArr: number[] = [];
876      let updateLength = 20; // Pass in 20 bytes by update() each time.
877      let tmpCipherText = new Uint8Array();
878
879      for (let i = 0; i <= plainText.length; i++) {
880        if ((i % updateLength == 0 || i == plainText.length) && messageArr.length != 0) {
881          let message = new Uint8Array(messageArr);
882          let messageBlob: cryptoFramework.DataBlob = { data: message };
883          let updateOutput = await globalCipher.update(messageBlob); // Update by segment.
884          // 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
885          // 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.
886          let mergeText = new Uint8Array(tmpCipherText.length + updateOutput.data.length);
887          mergeText.set(tmpCipherText);
888          mergeText.set(updateOutput.data, tmpCipherText.length);
889          tmpCipherText = mergeText;
890          // tmpCipherText = tmpCipherText.concat(Array.from(updateOutput.data));
891          messageArr = [];
892        }
893        if (i < plainText.length) {
894          messageArr.push(plainText.charCodeAt(i));
895        }
896      }
897      globalCipherText = { data: tmpCipherText };
898      return;
899    })
900    .then((): Promise<cryptoFramework.DataBlob> => {
901      return globalCipher.doFinal(null);
902    })
903    .then(tag => {
904      // In GCM mode, the encrypted authentication information needs to be obtained from the output of doFinal() and passed in globalGcmParams of init() in decryption.
905      globalGcmParams.authTag = tag;
906      return;
907    })
908    .then(() => {
909      // Initialize the Cipher instance and start decryption.
910      let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
911      return globalCipher.init(mode, globalKey, globalGcmParams);
912    })
913    .then(async () => {
914      let updateLength = 20;
915      let updateTimes = Math.ceil(globalCipherText.data.length / updateLength); // Round up to the nearest integer.
916      for (let i = 0; i < updateTimes; i++) {
917        let messageArr = globalCipherText.data.slice(i * updateLength, (i + 1) * updateLength);
918        let message = new Uint8Array(messageArr);
919        let messageBlob: cryptoFramework.DataBlob = { data: message };
920        let updateOutput = await globalCipher.update(messageBlob); // Update by segment.
921        globalPlainText += uint8ArrayToString(updateOutput.data); // Restore the original plaintext.
922      }
923      return;
924    })
925    .then((): Promise<cryptoFramework.DataBlob> => {
926      return globalCipher.doFinal(null);
927    })
928    .then(finalOutput => {
929      if (finalOutput == null) { // Check whether the result is null before using finalOutput.data.
930        console.info('GCM finalOutput is null');
931      }
932      console.info(`decrypt output: ${globalPlainText}`);
933    })
934    .catch((error: BusinessError) => {
935      console.error(`catch error, ${error.code}, ${error.message}`);
936    })
937}
938```
939
940### Encrypting and Decrypting Data Using RSA
941
942Encrypt and decrypt data using an RSA asymmetric key pair.
943
9441. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
9452. Create a **Cipher** instance.<br>Call **createCipher()** to create a **Cipher** instance, and set the key and encryption/decryption mode.
9463. Encrypt and decrypt data.<br>Call **doFinal()** provided by the **Cipher** instance to encrypt data or decrypt data.
947
948```ts
949import cryptoFramework from '@ohos.security.cryptoFramework';
950import { BusinessError } from '@ohos.base';
951
952let plan = "This is cipher test.";
953
954// Convert strings in plaintext into byte streams.
955function stringToUint8Array(str: string) {
956  let arr = new Uint8Array(str.length);
957  for (let i = 0, j = str.length; i < j; ++i) {
958    arr[i] = str.charCodeAt(i);
959  }
960  return arr;
961}
962
963// Encrypt the message in promise mode.
964function encryptMessagePromise() {
965  // Create an AsyKeyGenerator instance.
966  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
967  // Create a Cipher instance.
968  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
969  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
970  let keyGenPromise = rsaGenerator.generateKeyPair();
971  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
972    let pubKey = rsaKeyPair.pubKey;
973    // Initialize the Cipher instance and use the public key to encrypt the data.
974    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
975  }).then(() => {
976    // doFinal
977    let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
978    return cipher.doFinal(input);
979  }).then(dataBlob => {
980    // Obtain the encrypted data.
981    console.info("EncryptOutPut is " + dataBlob.data);
982  });
983}
984
985// Encrypt the message in callback mode.
986function encryptMessageCallback() {
987  // Create an AsyKeyGenerator instance.
988  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
989  // Create a Cipher instance.
990  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
991  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
992  rsaGenerator.generateKeyPair((err, keyPair) => {
993    let pubKey = keyPair.pubKey;
994    // Initialize the Cipher instance and use the public key to encrypt the data.
995    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, (err, data) => {
996      let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
997      // doFinal
998      cipher.doFinal(input, (err, data) => {
999        // Obtain the encrypted data.
1000        console.info("EncryptOutPut is " + data.data);
1001      })
1002    })
1003  })
1004}
1005
1006// Encrypt and decrypt the message in promise mode.
1007function decryptMessagePromise() {
1008  // Create an AsyKeyGenerator instance.
1009  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
1010  // Create a Cipher instance for encryption.
1011  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
1012  // Create a Cipher instance for decryption.
1013  let decoder = cryptoFramework.createCipher("RSA1024|PKCS1");
1014  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1015  let keyGenPromise = rsaGenerator.generateKeyPair();
1016  let keyPair: cryptoFramework.KeyPair;
1017  let cipherDataBlob: cryptoFramework.DataBlob;
1018  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
1019  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
1020    keyPair = rsaKeyPair;
1021    // Initialize the Cipher instance and use the public key to encrypt the message.
1022    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
1023  })
1024    .then(() => {
1025      // Call doFinal() to encrypt data.
1026      return cipher.doFinal(input);
1027    })
1028    .then((dataBlob: cryptoFramework.DataBlob): Promise<void> => {
1029      // Obtain the encrypted information and use it as the input parameter for decryption.
1030      console.info("EncryptOutPut is " + dataBlob.data);
1031      AlertDialog.show({ message: "output" + dataBlob.data });
1032      cipherDataBlob = dataBlob;
1033      // Initialize the Cipher instance and use the private key to decrypt the message.
1034      return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
1035    })
1036    .then(() => {
1037      // Call doFinal() to decrypt the data.
1038      return decoder.doFinal(cipherDataBlob);
1039    })
1040    .then(decodeData => {
1041      // Check whether the decrypted data is consistent with the original data.
1042      if (decodeData.data.toString() === input.data.toString()) {
1043        AlertDialog.show({ message: "decrypt success" });
1044        return;
1045      }
1046      AlertDialog.show({ message: "decrypt fail" });
1047    });
1048}
1049
1050// Encrypt and decrypt the message in callback mode.
1051function decryptMessageCallback() {
1052  // Create an AsyKeyGenerator instance.
1053  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
1054  // Create a Cipher instance for encryption.
1055  let cipher = cryptoFramework.createCipher("RSA1024|PKCS1");
1056  // Create a Cipher instance for decryption.
1057  let decoder = cryptoFramework.createCipher("RSA1024|PKCS1");
1058  let plainText = "this is cipher text";
1059  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plainText) };
1060  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1061  rsaGenerator.generateKeyPair((err, newKeyPair) => {
1062    let keyPair = newKeyPair;
1063    // Initialize the Cipher instance and use the public key to encrypt the message.
1064    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null, (err, data) => {
1065      // Call doFinal() to encrypt the message.
1066      cipher.doFinal(input, (err, data) => {
1067        // Obtain the encrypted information and use it as the input parameter for decryption.
1068        AlertDialog.show({ message: "EncryptOutPut is " + data.data });
1069        let cipherData = data;
1070        // Initialize the Cipher instance and use the private key to decrypt the message.
1071        decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null, (err, data) => {
1072          // Call doFinal() to decrypt the message.
1073          decoder.doFinal(cipherData, (err, data) => {
1074            // Check whether the decrypted data is consistent with the original data.
1075            if (input.data.toString() === data.data.toString()) {
1076              AlertDialog.show({ message: "decryption success" });
1077              return;
1078            }
1079            AlertDialog.show({ message: "decryption fail" });
1080          });
1081        });
1082      });
1083    });
1084  });
1085}
1086```
1087
1088### Encrypting and Decrypting Data Using RSA by Segment
1089
1090Use an RSA asymmetric key pair to encrypt and decrypt a large amount of data by segment.
1091
10921. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
10932. Create a **Cipher** instance.<br>Call **createCipher()** to create a **Cipher** instance, and set the key and encryption/decryption mode.
10943. Encrypt and decrypt data.<br>Call **doFinal()** provided by the **Cipher** instance multiple times to encrypt and decrypt data.
1095
1096```ts
1097import cryptoFramework from '@ohos.security.cryptoFramework';
1098import { BusinessError } from '@ohos.base';
1099
1100// Convert strings in plaintext into byte streams.
1101function stringToUint8Array(str: string) {
1102  let arr = new Uint8Array(str.length);
1103  for (let i = 0, j = str.length; i < j; ++i) {
1104    arr[i] = str.charCodeAt(i);
1105  }
1106  return arr;
1107}
1108
1109// Convert byte streams into strings in plaintext.
1110function uint8ArrayToString(array: Uint8Array) {
1111  let arrayString = '';
1112  for (let i = 0; i < array.length; i++) {
1113    arrayString += String.fromCharCode(array[i]);
1114  }
1115  return arrayString;
1116}
1117
1118function encryptLongMessagePromise() {
1119  let globalPlainText = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1120    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1121    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1122    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1123    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1124    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1125    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1126    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";
1127  let globalKeyPair: cryptoFramework.KeyPair;
1128  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.
1129  let cipherTextSplitLen = 128; // Length of the ciphertext = Number of key bits/8
1130  let keyGenName = "RSA1024";
1131  let cipherAlgName = "RSA1024|PKCS1";
1132  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // Create an AsyKeyGenerator object.
1133  let cipher = cryptoFramework.createCipher(cipherAlgName); // Create a Cipher object.
1134  let decoder = cryptoFramework.createCipher(cipherAlgName); // Create a Decoder object.
1135  let keyGenPromise = asyKeyGenerator.generateKeyPair(); // Generate an RSA key pair.
1136  let globalCipherText: cryptoFramework.DataBlob;
1137
1138  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
1139    globalKeyPair = rsaKeyPair; // Save the key pair as a global variable.
1140    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, globalKeyPair.pubKey, null);
1141  })
1142    .then(async () => {
1143      let tmpCipherText = new Uint8Array();
1144      // 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.
1145      for (let i = 0; i < (globalPlainText.length / plainTextSplitLen); i++) {
1146        let tempStr = globalPlainText.substr(i * plainTextSplitLen, plainTextSplitLen);
1147        let tempBlob: cryptoFramework.DataBlob = { data: stringToUint8Array(tempStr) };
1148        let tempCipherOutput = await cipher.doFinal(tempBlob);
1149        let mergeText = new Uint8Array(tmpCipherText.length + tempCipherOutput.data.length);
1150        mergeText.set(tmpCipherText);
1151        mergeText.set(tempCipherOutput.data, tmpCipherText.length);
1152        tmpCipherText = mergeText;
1153      }
1154      globalCipherText = { data: tmpCipherText };
1155      console.info(`globalCipherOutput len is ${tmpCipherText.length}, data is: ${tmpCipherText.toString()}`);
1156      return;
1157    })
1158    .then((): Promise<void> => {
1159      return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, globalKeyPair.priKey, null);
1160    })
1161    .then(async () => {
1162      let tmpDecodeText = new Uint8Array();
1163      // Split and decrypt the ciphertext by 128 bytes, and combine the plaintext obtained each time.
1164      for (let i = 0; i < (globalCipherText.data.length / cipherTextSplitLen); i++) {
1165        let tempBlobData = globalCipherText.data.slice(i * cipherTextSplitLen, (i + 1) * cipherTextSplitLen);
1166        let message = new Uint8Array(tempBlobData);
1167        let tempBlob: cryptoFramework.DataBlob = { data: message };
1168        let tempDecodeOutput = await decoder.doFinal(tempBlob);
1169        let mergeText = new Uint8Array(tmpDecodeText.length + tempDecodeOutput.data.length);
1170        mergeText.set(tmpDecodeText);
1171        mergeText.set(tempDecodeOutput.data, tmpDecodeText.length);
1172        tmpDecodeText = mergeText;
1173      }
1174      let globalDecodeOutput = uint8ArrayToString(tmpDecodeText);
1175      if (globalDecodeOutput === globalPlainText) {
1176        console.info(`encode and decode success`);
1177      } else {
1178        console.info(`encode and decode error`);
1179      }
1180      return;
1181    })
1182    .catch((error: BusinessError) => {
1183      console.error(`catch error, ${error.code}, ${error.message}`);
1184    })
1185}
1186```
1187
1188> **NOTE**
1189>
1190> - In RSA encryption and decryption, **init()** cannot be repeatedly called to initialize a **Cipher** instance. You must create a **Cipher** instance for each encryption and decryption.
1191> - The RSA encryption has a limit on the length of the plaintext to be encrypted. For details, see [Encryption and Decryption](cryptoFramework-overview.md#encryption-and-decryption).
1192> - 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.
1193
1194### Using PKCS1_OAEP in RSA Encryption and Decryption
1195
1196Use the PKCS1_OAEP padding mode in RSA encryption and decryption in promise mode.
1197
11981. Generate an RSA key pair based on the key parameters.<br>Call **createAsyKeyGeneratorBySpec()** to create an **AsyKeyGeneratorBySpec** object and generate an RSA asymmetric key pair. (You can also use **createAsyKeyGenerator()** to randomly generate or convert an RSA key object.)
11992. Create a **Cipher** instance.<br>Call **createCipher()** to create a cipher instance, initialize the cipher instance, set the key and encryption/decryption mode, use **setCipherSpec()** to set PKCS1_OAEP **pSource**, and use **update()** to pass in data.
12003. Encrypt and decrypt data.<br>Call the **doFinal()** API provided by the **Cipher** class to perform encryption or decryption. The **pSource** of the **Cipher** instance to be encrypted must be the same as that decrypted.
1201
1202```ts
1203import cryptoFramework from '@ohos.security.cryptoFramework';
1204import { BusinessError } from '@ohos.base';
1205
1206// Convert strings in plaintext into byte streams.
1207function stringToUint8Array(str: string) {
1208  let arr = new Uint8Array(str.length);
1209  for (let i = 0, j = str.length; i < j; ++i) {
1210    arr[i] = str.charCodeAt(i);
1211  }
1212  return arr;
1213}
1214
1215// Construct the key parameters of the RSA asymmetric key pair based on the key pair specifications.
1216function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
1217  let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
1218    n: nIn,
1219    algName: "RSA",
1220    specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
1221  };
1222  let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
1223    params: rsaCommSpec,
1224    sk: dIn,
1225    pk: eIn,
1226    algName: "RSA",
1227    specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
1228  };
1229  return rsaKeyPairSpec;
1230}
1231
1232// Generate RSA2048 key pair parameters.
1233function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
1234  let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
1235  let eIn = BigInt("0x010001");
1236  let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
1237  return genRsaKeyPairSpec(nIn, eIn, dIn);
1238}
1239
1240function rsaUseSpecDecryptOAEPPromise() {
1241  let plan = "This is cipher test.";
1242  // Obtain the key parameter object of the RSA key pair.
1243  let rsaKeyPairSpec = genRsa2048KeyPairSpec();
1244  // Generate an RSA key pair based on the RSA key parameters.
1245  let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
1246  let keyGenPromise = rsaGeneratorSpec.generateKeyPair();
1247  let cipher = cryptoFramework.createCipher("RSA|PKCS1_OAEP|SHA256|MGF1_SHA1");
1248  let decoder = cryptoFramework.createCipher("RSA|PKCS1_OAEP|SHA256|MGF1_SHA1");
1249  let keyPair: cryptoFramework.KeyPair;
1250  let cipherDataBlob: cryptoFramework.DataBlob;
1251  // Set the pSource, which defines the encoding input P filled by OAEP.
1252  let pSource = new Uint8Array([1, 2, 3, 4]);
1253  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
1254  // Generate the key pair.
1255  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
1256    keyPair = rsaKeyPair;
1257    // Initialize the Cipher instance for encryption.
1258    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
1259  })
1260    .then(() => {
1261      // Set and obtain the cipher specifications after the initialization.
1262      cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
1263      let retP = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
1264      // Check whether the obtained PSource is the same as the PSource set.
1265      if (retP.toString() != pSource.toString()) {
1266        AlertDialog.show({ message: "error init pSource" + retP });
1267      } else {
1268        console.info("pSource changed ==" + retP);
1269      }
1270      // Obtain other OAEP parameters.
1271      let md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
1272      console.info("md == " + md);
1273      let mgf = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
1274      console.info("mgf == " + mgf);
1275      let mgf1Md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
1276      console.info("mgf1Md == " + mgf1Md);
1277      return cipher.doFinal(input);
1278    })
1279    .then((dataBlob: cryptoFramework.DataBlob): Promise<void> => {
1280      console.info("EncryptOutPut is " + dataBlob.data);
1281      cipherDataBlob = dataBlob;
1282      // The get() and set() operations can be performed before the init() operation of the Cipher object and are equivalent to those after the init() operation. For example, set and get the decoder.
1283      decoder.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
1284      let retP = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
1285      // Check whether the obtained PSource is the same as the PSource set.
1286      if (retP.toString() != pSource.toString()) {
1287        AlertDialog.show({ message: "error init pSource" + retP });
1288      } else {
1289        console.info("pSource changed ==" + retP);
1290      }
1291      // Obtain other OAEP parameters.
1292      let md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
1293      console.info("md == " + md);
1294      let mgf = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
1295      console.info("mgf == " + mgf);
1296      let mgf1Md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
1297      console.info("mgf1Md == " + mgf1Md);
1298      // Initialize the decryption operation.
1299      return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
1300    })
1301    .then(() => {
1302      return decoder.doFinal(cipherDataBlob);
1303    })
1304    .then(decodeData => {
1305      // The decryption is successful.
1306      if (decodeData.data.toString() === input.data.toString()) {
1307        console.info("oaep decrypt success");
1308        AlertDialog.show({ message: " oaep decrypt success" });
1309      } else {
1310        AlertDialog.show({ message: "oeap decrypt fail" });
1311      }
1312    });
1313}
1314```
1315
1316### Encrypting and Decrypting Data Using SM2
1317
1318> **NOTE**
1319>
1320> SM2 encryption and decryption are supported from API version 10.
1321
1322Use an SM2 asymmetric key pair to encrypt and decrypt data.
1323
13241. Generate an SM2 key pair. Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an SM2 asymmetric key pair.
13252. Create a **Cipher** instance.<br>Call **createCipher()** to create a **Cipher** instance, and set the key and encryption/decryption mode.
13263. Encrypt and decrypt data.<br>Call **doFinal()** provided by the **Cipher** instance to encrypt data or decrypt data.
1327
1328```ts
1329import cryptoFramework from '@ohos.security.cryptoFramework';
1330import { BusinessError } from '@ohos.base';
1331
1332let plan = "This is cipher test.";
1333
1334// Convert strings in plaintext into byte streams.
1335function stringToUint8Array(str: string) {
1336  let arr = new Uint8Array(str.length);
1337  for (let i = 0, j = str.length; i < j; ++i) {
1338    arr[i] = str.charCodeAt(i);
1339  }
1340  return arr;
1341}
1342
1343// Encrypt the message in promise mode.
1344function encryptMessagePromise() {
1345  // Create an AsyKeyGenerator instance.
1346  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
1347  // Create a Cipher instance.
1348  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
1349  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1350  let keyGenPromise = sm2Generator.generateKeyPair();
1351  keyGenPromise.then((sm2KeyPair: cryptoFramework.KeyPair): Promise<void> => {
1352    let pubKey = sm2KeyPair.pubKey;
1353    // Initialize the Cipher instance and use the public key to encrypt the message.
1354    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);
1355  }).then(() => {
1356    // doFinal
1357    let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
1358    return cipher.doFinal(input);
1359  }).then(dataBlob => {
1360    // Obtain the encrypted data.
1361    console.info("EncryptOutPut is " + dataBlob.data);
1362  });
1363}
1364
1365// Encrypt the message in callback mode.
1366function encryptMessageCallback() {
1367  // Create an AsyKeyGenerator instance.
1368  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
1369  // Create a Cipher instance.
1370  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
1371  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1372  sm2Generator.generateKeyPair((err, keyPair) => {
1373    let pubKey = keyPair.pubKey;
1374    // Initialize the Cipher instance and use the public key to encrypt the message.
1375    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null, (err, data) => {
1376      let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
1377      // doFinal
1378      cipher.doFinal(input, (err, data) => {
1379        // Obtain the encrypted data.
1380        console.info("EncryptOutPut is " + data.data);
1381      })
1382    })
1383  })
1384}
1385
1386// Encrypt and decrypt data in promise mode.
1387function decryptMessagePromise() {
1388  // Create an AsyKeyGenerator instance.
1389  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
1390  // Create a Cipher instance for encryption.
1391  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
1392  // Create a Cipher instance for decryption.
1393  let decoder = cryptoFramework.createCipher("SM2_256|SM3");
1394  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1395  let keyGenPromise = sm2Generator.generateKeyPair();
1396  let keyPair: cryptoFramework.KeyPair;
1397  let cipherDataBlob: cryptoFramework.DataBlob;
1398  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plan) };
1399  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
1400    keyPair = rsaKeyPair;
1401    // Initialize the Cipher instance and use the public key to encrypt the data.
1402    return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
1403  })
1404    .then(() => {
1405      // Call doFinal() to encrypt data.
1406      return cipher.doFinal(input);
1407    })
1408    .then((dataBlob: cryptoFramework.DataBlob): Promise<void> => {
1409      // Obtain the encrypted information and use it as the input parameter for decryption.
1410      console.info("EncryptOutPut is " + dataBlob.data);
1411      AlertDialog.show({ message: "output" + dataBlob.data });
1412      cipherDataBlob = dataBlob;
1413      // Initialize the Cipher instance and use the private key to decrypt the data.
1414      return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
1415    })
1416    .then(() => {
1417      // Call doFinal() to decrypt data.
1418      return decoder.doFinal(cipherDataBlob);
1419    })
1420    .then(decodeData => {
1421      // Check whether the decrypted data is consistent with the original data.
1422      if (decodeData.data.toString() === input.data.toString()) {
1423        AlertDialog.show({ message: "decrypt success" });
1424        return;
1425      }
1426      AlertDialog.show({ message: "decrypt fail" });
1427    });
1428}
1429
1430// Encrypt and decrypt data in callback mode.
1431function decryptMessageCallback() {
1432  // Create an AsyKeyGenerator instance.
1433  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
1434  // Create a Cipher instance for encryption.
1435  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
1436  // Create a Cipher instance for decryption.
1437  let decoder = cryptoFramework.createCipher("SM2_256|SM3");
1438  let plainText = "this is cipher text";
1439  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plainText) };
1440  let cipherData: cryptoFramework.DataBlob;
1441  let keyPair: cryptoFramework.KeyPair;
1442  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1443  sm2Generator.generateKeyPair((err, newKeyPair) => {
1444    keyPair = newKeyPair;
1445    // Initialize the Cipher instance and use the public key to encrypt the data.
1446    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null, (err, data) => {
1447      // Call doFinal() to encrypt data.
1448      cipher.doFinal(input, (err, data) => {
1449        // Obtain the encrypted information and use it as the input parameter for decryption.
1450        AlertDialog.show({ message: "EncryptOutPut is " + data.data });
1451        cipherData = data;
1452        // Initialize the Cipher instance and use the private key to decrypt the data.
1453        decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null, (err, data) => {
1454          // Call doFinal() to decrypt data.
1455          decoder.doFinal(cipherData, (err, data) => {
1456            // Check whether the decrypted data is consistent with the original data.
1457            if (input.data.toString() === data.data.toString()) {
1458              AlertDialog.show({ message: "decrypt success" });
1459              return;
1460            }
1461            AlertDialog.show({ message: "decrypt fail" });
1462          });
1463        });
1464      });
1465    });
1466  });
1467}
1468```
1469
1470### Encrypting and Decrypting Data Using an SM4 ECB Symmetric Key (Callback)
1471
1472> **NOTE**
1473>
1474> SM4 encryption and decryption are supported from API version 10.
1475
1476Use an SM4 symmetric key to encrypt and decrypt data.
1477
14781. Create a **SymKeyGenerator** instance.
14792. Generate a key based on the existing binary data.
14803. Create a **Cipher** instance.
14814. Encrypt or decrypt data.
1482
1483```ts
1484import cryptoFramework from '@ohos.security.cryptoFramework';
1485import { BusinessError } from '@ohos.base';
1486
1487// Convert strings in plaintext into byte streams.
1488function stringToUint8Array(str: string) {
1489  let arr = new Uint8Array(str.length);
1490  for (let i = 0, j = str.length; i < j; ++i) {
1491    arr[i] = str.charCodeAt(i);
1492  }
1493  return arr;
1494}
1495
1496// Convert byte streams into strings in plaintext.
1497function uint8ArrayToString(array: Uint8Array) {
1498  let arrayString = '';
1499  for (let i = 0; i < array.length; i++) {
1500    arrayString += String.fromCharCode(array[i]);
1501  }
1502  return arrayString;
1503}
1504
1505// Use SM4 ECB to encrypt and decrypt a message in callback mode.
1506function testSM4Ecb() {
1507  // Create an AsyKeyGenerator instance.
1508  let sm4Generator = cryptoFramework.createSymKeyGenerator('SM4_128');
1509  // Create a Cipher instance for encryption.
1510  let cipher = cryptoFramework.createCipher("SM4_128|ECB|PKCS7");
1511  // Create a Cipher instance for decryption.
1512  let decoder = cryptoFramework.createCipher("SM4_128|ECB|PKCS7");
1513  let plainText = "this is cipher text";
1514  let input: cryptoFramework.DataBlob = { data: stringToUint8Array(plainText) };
1515  let cipherData: cryptoFramework.DataBlob;
1516  let key: cryptoFramework.SymKey;
1517  // Generate an asymmetric key pair using the AsyKeyGenerator instance.
1518  sm4Generator.generateSymKey((err, newKey) => {
1519    key = newKey;
1520    // Initialize the Cipher instance and use the public key to encrypt the data.
1521    cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, key, null, (err, data) => {
1522      // Call doFinal() to encrypt data.
1523      cipher.doFinal(input, (err, data) => {
1524        // Obtain the encrypted information and use it as the input parameter for decryption.
1525        AlertDialog.show({ message: "EncryptOutPut is " + data.data });
1526        cipherData = data;
1527        // Initialize the Cipher instance and use the private key to decrypt the data.
1528        decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, key, null, (err, data) => {
1529          // Call doFinal() to decrypt data.
1530          decoder.doFinal(cipherData, (err, data) => {
1531            // Check whether the decrypted data is consistent with the original data.
1532            if (input.data.toString() === data.data.toString()) {
1533              AlertDialog.show({ message: "decrypt success" });
1534              return;
1535            }
1536            AlertDialog.show({ message: "decrypt fail" });
1537          });
1538        });
1539      });
1540    });
1541  });
1542}
1543```
1544
1545## Signing and Signature Verification
1546
1547### When to Use
1548
1549A digital signature can be used to verify the authenticity of a message. Typical signing and signature verification operations involve the following:
15501. Use RSA to generate a signature and verify the signature.
15512. Use ECC to generate a signature and verify the signature.
15523. Use RSA to generate a signature and verify the signature. Obtain and set **SignSpecItem** when the PSS padding mode is used.
15534. Use SM2 to generate a signature and verify the signature.
1554
1555> **NOTE**
1556>
1557> - From API version 10, [SignSpecItem](../reference/apis/js-apis-cryptoFramework.md#signspecitem10) can be set and obtained when the PSS padding mode is used.
1558> - From API version 10, the string parameter without the key length is supported in signature verification.
1559
1560### Available APIs
1561
1562The following table describes the APIs used in typical signing and signature verification operations. For more information about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
1563> **NOTE**
1564>
1565> Due to 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 to ensure correct use of these APIs.
1566
1567|Instance|API|Description|
1568|---|---|---|
1569|cryptoFramework|createSign(algName : string) : Sign|Creates a **Sign** instance.|
1570|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.|
1571|Sign|init(priKey : PriKey) : Promise\<void>|Sets a key and initializes the **Sign** instance. This API uses a promise to return the result.|
1572|Sign|update(data : DataBlob, callback : AsyncCallback\<void>) : void|Updates the data for signing. This API uses an asynchronous callback to return the result.|
1573|Sign|update(data : DataBlob) : Promise\<void>|Updates the data for signing. This API uses a promise to return the result.|
1574|Sign|sign(data : DataBlob, callback : AsyncCallback\<DataBlob>) : void|Signs the data. This API uses an asynchronous callback to return the result.|
1575|Sign|sign(data : DataBlob) : Promise\<DataBlob>|Signs the data. This API uses a promise to return the result.|
1576|Sign|getSignSpec(itemType: SignSpecItem): string \| number|Obtains signing specifications. Currently, only the RSA is supported.|
1577|Sign|setSignSpec(itemType: SignSpecItem, itemValue: number): void|Sets signing specifications. Currently, only the RSA is supported.|
1578|cryptoFramework|function createVerify(algName : string) : Verify|Creates a **Verify** instance.|
1579|Verify|init(pubKey : PubKey, callback : AsyncCallback\<void>) : void|Sets a key and initializes the **Verify** instance. This API uses an asynchronous callback to return the result.|
1580|Verify|init(pubKey : PubKey) : Promise\<void>|Sets a key and initializes the **Verify** instance. This API uses a promise to return the result.|
1581|Verify|update(data : DataBlob, callback : AsyncCallback\<void>) : void|Updates the data for signature verification. This API uses an asynchronous callback to return the result.|
1582|Verify|update(data : DataBlob) : Promise\<void>|Updates the data for signature verification. This API uses a promise to return the result.|
1583|Verify|verify(data : DataBlob, signatureData : DataBlob, callback : AsyncCallback\<boolean>) : void|Verifies a signature. This API uses an asynchronous callback to return the result.|
1584|Verify|verify(data : DataBlob, signatureData : DataBlob) : Promise\<boolean>|Verifies a signature. This API uses a promise to return the result.|
1585|Verify|getVerifySpec(itemType: SignSpecItem): string \| number|Obtains signature verification specifications. Currently, only the RSA is supported.|
1586|Verify|setVerifySpec(itemType: SignSpecItem, itemValue: number): void|Sets signature verification specifications. Currently, only the RSA is supported.|
1587
1588### Signing and Signature Verification Using RSA
1589
1590Use RSA to sign data and verify the signature.
1591
15921. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
15932. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
15943. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **sign()** to generate a signature.
15954. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
15965. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **verify()** to verify the signature.
1597
1598```ts
1599import cryptoFramework from '@ohos.security.cryptoFramework';
1600import { BusinessError } from '@ohos.base';
1601
1602// Convert strings in plaintext into byte streams.
1603function stringToUint8Array(str: string) {
1604  let arr = new Uint8Array(str.length);
1605  for (let i = 0, j = str.length; i < j; ++i) {
1606    arr[i] = str.charCodeAt(i);
1607  }
1608  return arr;
1609}
1610
1611let globalKeyPair: cryptoFramework.KeyPair;
1612let signMessageBlob: cryptoFramework.DataBlob;
1613let plan1 = "This is Sign test plan1";
1614let plan2 = "This is Sign test plan1";
1615let input1: cryptoFramework.DataBlob = { data: stringToUint8Array(plan1) };
1616let input2: cryptoFramework.DataBlob = { data: stringToUint8Array(plan2) };
1617
1618function signMessagePromise() {
1619  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
1620  let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); // From API version 10, a Sign instance can be created by specifying a string parameter defining the key specifications.
1621  let keyGenPromise = rsaGenerator.generateKeyPair();
1622  keyGenPromise.then(keyPair => {
1623    globalKeyPair = keyPair;
1624    let priKey = globalKeyPair.priKey;
1625    return signer.init(priKey);
1626  }).then(() => {
1627    return signer.update(input1);
1628  }).then(() => {
1629    return signer.sign(input2);
1630  }).then(dataBlob => {
1631    signMessageBlob = dataBlob;
1632    console.info("sign output is " + signMessageBlob.data);
1633  });
1634}
1635
1636// Call verify() after sign() is called.
1637function verifyMessagePromise() {
1638  let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256");
1639  let verifyInitPromise = verifyer.init(globalKeyPair.pubKey);
1640  verifyInitPromise.then(() => {
1641    return verifyer.update(input1);
1642  }).then(() => {
1643    return verifyer.verify(input2, signMessageBlob);
1644  }).then(res => {
1645    console.log("Verify result is " + res);
1646  });
1647}
1648
1649function signMessageCallback() {
1650  let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
1651  let signer = cryptoFramework.createSign("RSA1024|PKCS1|SHA256"); // From API version 10, a Sign instance can be created by specifying a string parameter defining the key specifications.
1652  rsaGenerator.generateKeyPair((err, keyPair) => {
1653    globalKeyPair = keyPair;
1654    let priKey = globalKeyPair.priKey;
1655    signer.init(priKey, err => {
1656      signer.update(input1, err => {
1657        signer.sign(input2, (err, data) => {
1658          signMessageBlob = data;
1659          console.info("sign output is " + signMessageBlob.data);
1660        });
1661      });
1662    });
1663  });
1664}
1665
1666// Call verify() after sign() is called.
1667function verifyMessageCallback() {
1668  let verifyer = cryptoFramework.createVerify("RSA1024|PKCS1|SHA256");
1669  verifyer.init(globalKeyPair.pubKey, err => {
1670    verifyer.update(input1, err => {
1671      verifyer.verify(input2, signMessageBlob, (err, data) => {
1672        console.info("verify result is " + data);
1673      });
1674    });
1675  })
1676}
1677```
1678
1679### Signing and Signature Verification Using ECDSA
1680
1681Use ECDSA to sign data and verify the signature.
1682
16831. Generate an ECC key.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an ECC asymmetric key pair.
16842. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
16853. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **doFinal()** to generate a signature.
16864. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
16875. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **doFinal()** to verify the signature.
1688
1689```ts
1690import cryptoFramework from '@ohos.security.cryptoFramework';
1691import { BusinessError } from '@ohos.base';
1692
1693// Convert strings in plaintext into byte streams.
1694function stringToUint8Array(str: string) {
1695  let arr = new Uint8Array(str.length);
1696  for (let i = 0, j = str.length; i < j; ++i) {
1697    arr[i] = str.charCodeAt(i);
1698  }
1699  return arr;
1700}
1701
1702let globalKeyPair: cryptoFramework.KeyPair;
1703let signMessageBlob: cryptoFramework.DataBlob;
1704let plan1 = "This is Sign test plan1";
1705let plan2 = "This is Sign test plan1";
1706let input1: cryptoFramework.DataBlob = { data: stringToUint8Array(plan1) };
1707let input2: cryptoFramework.DataBlob = { data: stringToUint8Array(plan2) };
1708
1709function signMessagePromise() {
1710  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
1711  let signer = cryptoFramework.createSign("ECC256|SHA256");
1712  let keyGenPromise = eccGenerator.generateKeyPair();
1713  keyGenPromise.then(keyPair => {
1714    globalKeyPair = keyPair;
1715    let priKey = globalKeyPair.priKey;
1716    return signer.init(priKey);
1717  }).then(() => {
1718    return signer.update(input1);
1719  }).then(() => {
1720    return signer.sign(input2);
1721  }).then(dataBlob => {
1722    signMessageBlob = dataBlob;
1723    console.info("sign output is " + signMessageBlob.data);
1724  });
1725}
1726
1727function verifyMessagePromise() {
1728  let verifyer = cryptoFramework.createVerify("ECC256|SHA256");
1729  let verifyInitPromise = verifyer.init(globalKeyPair.pubKey);
1730  verifyInitPromise.then(() => {
1731    return verifyer.update(input1);
1732  }).then(() => {
1733    return verifyer.verify(input2, signMessageBlob);
1734  }).then(res => {
1735    console.log("Verify result is " + res);
1736  });
1737}
1738
1739function signMessageCallback() {
1740  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
1741  let signer = cryptoFramework.createSign("ECC256|SHA256");
1742  eccGenerator.generateKeyPair((err, keyPair) => {
1743    globalKeyPair = keyPair;
1744    let priKey = globalKeyPair.priKey;
1745    signer.init(priKey, err => {
1746      signer.update(input1, err => {
1747        signer.sign(input2, (err, data) => {
1748          signMessageBlob = data;
1749          console.info("sign output is " + signMessageBlob.data);
1750        });
1751      });
1752    });
1753  });
1754}
1755
1756function verifyMessageCallback() {
1757  let verifyer = cryptoFramework.createVerify("ECC256|SHA256");
1758  verifyer.init(globalKeyPair.pubKey, err => {
1759    verifyer.update(input1, err => {
1760      verifyer.verify(input2, signMessageBlob, (err, data) => {
1761        console.info("verify result is " + data);
1762      });
1763    });
1764  })
1765}
1766```
1767
1768### Signing and Signature Verification Using RSA by Segment
1769
1770Use RSA to sign data and verify the signature by segment.
1771
17721. Generate an RSA key pair.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an RSA asymmetric key pair.
17732. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
17743. Generate a signature.<br>Call the **update()** provided by the **Sign** class multiple times to pass in data by segment and call **sign()** to generate a signature.
17754. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
17765. Verify the signature.<br>Call the **update()** method provided by the **Verify** class multiple times to pass in data by segment and call **verify()** to verify the signature.
1777
1778```ts
1779import cryptoFramework from '@ohos.security.cryptoFramework';
1780import { BusinessError } from '@ohos.base';
1781
1782// Convert strings in plaintext into byte streams.
1783function stringToUint8Array(str: string) {
1784  let arr = new Uint8Array(str.length);
1785  for (let i = 0, j = str.length; i < j; ++i) {
1786    arr[i] = str.charCodeAt(i);
1787  }
1788  return arr;
1789}
1790
1791function signLongMessagePromise() {
1792  let globalPlainText = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1793    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1794    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1795    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1796    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1797    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1798    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +
1799    "This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";
1800  let globalSignData: Uint8Array;
1801  let textSplitLen = 64; // Customized data splitting length.
1802  let keyGenName = "RSA1024";
1803  let signAlgName = "RSA1024|PKCS1|SHA256";
1804  let globalKeyPair: cryptoFramework.KeyPair;
1805  let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // Create an AsyKeyGenerator object.
1806  let signer = cryptoFramework.createSign(signAlgName); // Create a Signer instance.
1807  let verifier = cryptoFramework.createVerify(signAlgName); // Create a Verifier instance.
1808  let keyGenPromise = asyKeyGenerator.generateKeyPair();
1809  keyGenPromise.then((rsaKeyPair: cryptoFramework.KeyPair): Promise<void> => {
1810    globalKeyPair = rsaKeyPair; // Save the key pair as a global variable.
1811    return signer.init(globalKeyPair.priKey);
1812  })
1813    .then(async (): Promise<void> => {
1814      // If the plaintext is too large, split the plaintext based on the specified length and cyclically call update() to pass in the plaintext.
1815      for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1816        let tempStr = globalPlainText.substr(i * textSplitLen, textSplitLen);
1817        let tempBlob: cryptoFramework.DataBlob = { data: stringToUint8Array(tempStr) };
1818        await signer.update(tempBlob);
1819      }
1820    })
1821    .then((): Promise<cryptoFramework.DataBlob> => {
1822      return signer.sign(null);
1823    })
1824    .then((signData: cryptoFramework.DataBlob): Promise<void> => {
1825      globalSignData = signData.data;
1826      console.info(`globalSignOutput len is ${globalSignData.length}, data is: ${globalSignData.toString()}`);
1827      return verifier.init(globalKeyPair.pubKey);
1828    })
1829    .then(async () => {
1830      // If the plaintext is too large, split the plaintext based on the specified length and cyclically call update() to pass in the plaintext.
1831      for (let i = 0; i < (globalPlainText.length / textSplitLen); i++) {
1832        let tempData = globalPlainText.slice(i * textSplitLen, (i + 1) * textSplitLen);
1833        let tempBlob: cryptoFramework.DataBlob = { data: stringToUint8Array(tempData) };
1834        await verifier.update(tempBlob);
1835      }
1836      return;
1837    })
1838    .then((): Promise<boolean> => {
1839      return verifier.verify(null, { data: globalSignData });
1840    })
1841    .then(res => {
1842      console.info(`verify res is ${res}`);
1843    })
1844    .catch((error: BusinessError) => {
1845      console.error(`catch error, ${error.code}, ${error.message}`);
1846    })
1847}
1848```
1849
1850### Using PSS in RSA Signing and Signature Verification
1851
1852Use the PSS padding mode in RSA signing and signature verification in callback mode.
1853
18541. Generate an RSA key pair based on the key parameters.<br>Call **createAsyKeyGeneratorBySpec** to create an **AsyKeyGeneratorBySpec** object and generate an RSA asymmetric key pair.
18552. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** object, initialize the **Sign** object, set the private key for signing, and set and obtain PSS parameters.
18563. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **sign()** to generate a signature.
18574. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** object, initialize the object, set the public key for signature verification, and set and obtain PSS parameters. The signature verification is successful if the salt length is the same.
18585. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **verify()** to verify the signature.
1859
1860```ts
1861import cryptoFramework from '@ohos.security.cryptoFramework';
1862import { BusinessError } from '@ohos.base';
1863
1864// Convert strings in plaintext into byte streams.
1865function stringToUint8Array(str: string) {
1866  let arr = new Uint8Array(str.length);
1867  for (let i = 0, j = str.length; i < j; ++i) {
1868    arr[i] = str.charCodeAt(i);
1869  }
1870  return arr;
1871}
1872
1873// Convert byte streams into strings in plaintext.
1874function uint8ArrayToString(array: Uint8Array) {
1875  let arrayString = '';
1876  for (let i = 0; i < array.length; i++) {
1877    arrayString += String.fromCharCode(array[i]);
1878  }
1879  return arrayString;
1880}
1881
1882// Construct the key parameters of the RSA asymmetric key pair based on the key pair specifications.
1883function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
1884  let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
1885    n: nIn,
1886    algName: "RSA",
1887    specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
1888  };
1889  let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
1890    params: rsaCommSpec,
1891    sk: dIn,
1892    pk: eIn,
1893    algName: "RSA",
1894    specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
1895  };
1896  return rsaKeyPairSpec;
1897}
1898
1899// Generate RSA2048 key pair parameters.
1900function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
1901  let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
1902  let eIn = BigInt("0x010001");
1903  let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
1904  return genRsaKeyPairSpec(nIn, eIn, dIn);
1905}
1906
1907function verifyMessageCallbackPSS() {
1908  let plan1 = "This is Sign test plan1";
1909  let plan2 = "This is Sign test plan1";
1910  let input1: cryptoFramework.DataBlob = { data: stringToUint8Array(plan1) };
1911  let input2: cryptoFramework.DataBlob = { data: stringToUint8Array(plan2) };
1912  let globalKeyPair: cryptoFramework.KeyPair;
1913  let signMessageBlob: cryptoFramework.DataBlob;
1914  // Obtain the key parameter object of the RSA key pair.
1915  let rsaKeyPairSpec = genRsa2048KeyPairSpec();
1916  // Create an RSA key pair generator.
1917  let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
1918  // Both sign() and verify() support the RSA key with or without the length.
1919  let signer = cryptoFramework.createSign("RSA|PSS|SHA256|MGF1_SHA256");
1920  let verifyer = cryptoFramework.createVerify("RSA2048|PSS|SHA256|MGF1_SHA256");
1921  rsaGeneratorSpec.generateKeyPair((err, keyPair) => {
1922    globalKeyPair = keyPair;
1923    signer.init(globalKeyPair.priKey, err => {
1924      // After the initialization, set and obtain the PSS parameters.
1925      let setN = 32;
1926      signer.setSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
1927      let saltLen = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
1928      console.info("SaltLen == " + saltLen);
1929      let tf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
1930      console.info("trailer field == " + tf);
1931      let md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
1932      console.info("md == " + md);
1933      let mgf = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
1934      console.info("mgf == " + mgf);
1935      let mgf1Md = signer.getSignSpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
1936      console.info("mgf1Md == " + mgf1Md);
1937      signer.update(input1, err => {
1938        signer.sign(input2, (err, data) => {
1939          // Before signature verification initialization, set and obtain PSS parameters. The functions are the same as those after initialization.
1940          signMessageBlob = data;
1941          AlertDialog.show({ message: "res" + signMessageBlob.data });
1942          let setN = 32;
1943          verifyer.setVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM, setN);
1944          let saltLen = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_SALT_LEN_NUM);
1945          console.info("SaltLen == " + saltLen);
1946          let tf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_TRAILER_FIELD_NUM);
1947          console.info("trailer field == " + tf);
1948          let md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MD_NAME_STR);
1949          console.info("md == " + md);
1950          let mgf = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF_NAME_STR);
1951          console.info("mgf == " + mgf);
1952          let mgf1Md = verifyer.getVerifySpec(cryptoFramework.SignSpecItem.PSS_MGF1_MD_STR);
1953          console.info("mgf1Md == " + mgf1Md);
1954          verifyer.init(globalKeyPair.pubKey, err => {
1955            verifyer.update(input1, err => {
1956              verifyer.verify(input2, signMessageBlob, (err, data) => {
1957                AlertDialog.show({ message: "res " + data });
1958              })
1959            });
1960          });
1961        });
1962      });
1963    });
1964  });
1965}
1966```
1967
1968### Signing and Signature Verification Using SM2
1969
1970> **NOTE**
1971>
1972> SM2 signing and signature verification are supported from API version 10.
1973
1974Use SM2 to sign data and verify the signature.
1975
19761. Generate an SM2 key pair. Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an SM2 asymmetric key pair.
19772. Create a **Sign** instance.<br>Call **createSign()** to create a **Sign** instance, initialize the **Sign** instance, and set a private key for signing.
19783. Generate a signature.<br>Call **update()** provided by the **Sign** class to pass in the data for signing and call **doFinal()** to generate a signature.
19794. Create a **Verify** instance.<br>Call **createVerify()** to create a **Verify** instance, initialize the instance, and set a public key for signature verification.
19805. Verify the signature.<br>Call **update()** provided by the **Verify** class to pass in the signature data and call **doFinal()** to verify the signature.
1981
1982```ts
1983import cryptoFramework from '@ohos.security.cryptoFramework';
1984import { BusinessError } from '@ohos.base';
1985
1986// Convert strings in plaintext into byte streams.
1987function stringToUint8Array(str: string) {
1988  let arr = new Uint8Array(str.length);
1989  for (let i = 0, j = str.length; i < j; ++i) {
1990    arr[i] = str.charCodeAt(i);
1991  }
1992  return arr;
1993}
1994
1995let plan1 = "This is Sign test plan1";
1996let plan2 = "This is Sign test plan2";
1997let input1: cryptoFramework.DataBlob = { data: stringToUint8Array(plan1) };
1998let input2: cryptoFramework.DataBlob = { data: stringToUint8Array(plan2) };
1999
2000function signAndVerify() {
2001  let signMessageBlob: cryptoFramework.DataBlob;
2002  let sm2Generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
2003  let signer = cryptoFramework.createSign("SM2_256|SM3");
2004  sm2Generator.generateKeyPair((err, keyPair) => {
2005    let priKey = keyPair.priKey;
2006    signer.init(priKey, err => {
2007      signer.update(input1, err => {
2008        signer.sign(input2, (err, data) => {
2009          signMessageBlob = data;
2010          console.info("sign output is " + signMessageBlob.data);
2011          let verifyer = cryptoFramework.createVerify("SM2_256|SM3");
2012          verifyer.init(keyPair.pubKey, err => {
2013            verifyer.update(input1, err => {
2014              verifyer.verify(input2, signMessageBlob, (err, data) => {
2015                console.info("verify result is " + data);
2016                AlertDialog.show({ message: "verify success" })
2017              });
2018            });
2019          })
2020        });
2021      });
2022    });
2023  });
2024}
2025```
2026
2027## Key Agreement
2028
2029### When to Use
2030
2031
2032Key agreement allows two parties to establish a shared secret over an insecure channel.
2033
2034> **NOTE**
2035>
2036> From API version 10, the string parameter without the key length is supported in key agreement.
2037
2038### Available APIs
2039
2040For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
2041
2042|Instance|API|Description|
2043|---|---|---|
2044|cryptoFramework|createKeyAgreement(algName : string) : KeyAgreement|Creates a **KeyAgreement** instance.|
2045|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey, callback : AsyncCallback\<DataBlob>) : void|Generates a shared secret. This API uses an asynchronous callback to return the result.|
2046|KeyAgreement|generateSecret(priKey : PriKey, pubKey : PubKey) : Promise\<DataBlob>|Generates a shared secret. This API uses a promise to return the result.|
2047
2048### How to Develop
2049
20501. Generate an ECC key.<br>Call **createAsyKeyGenerator()** to create an **AsyKeyGenerator** instance and generate an ECC asymmetric key pair.
20512. Generate a shared secret by using the private and public ECC keys.
2052
2053```ts
2054import cryptoFramework from '@ohos.security.cryptoFramework';
2055import { BusinessError } from '@ohos.base';
2056
2057let globalKeyPair: cryptoFramework.KeyPair;
2058
2059function ecdhPromise() {
2060  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
2061  let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256"); // ECC is supported for key agreement from API version 10.
2062  let keyGenPromise = eccGenerator.generateKeyPair();
2063  keyGenPromise.then(keyPair => {
2064    globalKeyPair = keyPair;
2065    return eccKeyAgreement.generateSecret(keyPair.priKey, keyPair.pubKey);
2066  }).then((secret) => {
2067    console.info("ecdh output is " + secret.data);
2068  }).catch((error: BusinessError) => {
2069    console.error("ecdh error.");
2070  });
2071}
2072
2073function ecdhCallback() {
2074  let eccGenerator = cryptoFramework.createAsyKeyGenerator("ECC256");
2075  let eccKeyAgreement = cryptoFramework.createKeyAgreement("ECC256");
2076  eccGenerator.generateKeyPair((err, keyPair) => {
2077    globalKeyPair = keyPair;
2078    eccKeyAgreement.generateSecret(keyPair.priKey, keyPair.pubKey, (err, secret) => {
2079      if (err) {
2080        console.error("ecdh error.");
2081        return;
2082      }
2083      console.info("ecdh output is " + secret.data);
2084    });
2085  });
2086}
2087```
2088
2089## Message Digest
2090
2091### When to Use
2092
2093A message digest (MD) is a fixed size numeric representation of the content of a message, computed by a hash 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.
2094
2095Typical MD operations involve the following:
2096
20971. Create an **Md** instance with the specified digest algorithm (such as SHA-256).
20982. Pass in one or more messages for generating a digest, and generate a digest.
20993. Obtain the digest algorithm and digest length (in bytes).
2100
2101### Available APIs
2102
2103For more information about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
2104
2105| Instance         | API                                                      | Description                                              |
2106| --------------- | ------------------------------------------------------------ | -------------------------------------------------- |
2107| cryptoFramework | function createMd(algName : string) : Md;                    | Creates an **Md** instance with the specified algorithm. |
2108| Md              | update(input : DataBlob, callback : AsyncCallback\<void>) : void; | Updates the data for a digest. This API uses an asynchronous callback to return the result.|
2109| Md              | update(input : DataBlob) : Promise\<void>;                  | Updates the data for a digest. This API uses a promise to return the result. |
2110| Md              | digest(callback : AsyncCallback\<DataBlob>) : void;         | Generates the digest. This API uses an asynchronous callback to return the result.                      |
2111| Md              | digest() : Promise\<DataBlob>;                              | Generates the digest. This API uses a promise to return the result.                       |
2112| Md              | getMdLength() : number;                                      | Obtains the digest length based on the specified digest algorithm.            |
2113| Md              | readonly algName : string;                                   | Obtains the digest algorithm.                          |
2114
2115### Generating a Digest
2116
21171. Use **createMd()** to create an **Md** instance.
21182. Use **update()** to pass in data. **update()** can be called multiple times. The algorithm library does not limit the data length of a single **update()**.
21193. Use **digest()** to compute a digest.
21204. Obtain the digest algorithm and length of the digest generated.
2121
2122```ts
2123import cryptoFramework from '@ohos.security.cryptoFramework';
2124import { BusinessError } from '@ohos.base';
2125
2126// Convert strings in plaintext into byte streams.
2127function stringToUint8Array(str: string) {
2128  let arr = new Uint8Array(str.length);
2129  for (let i = 0, j = str.length; i < j; ++i) {
2130    arr[i] = str.charCodeAt(i);
2131  }
2132  return arr;
2133}
2134
2135// Generate a digest in promise mode.
2136function doMdByPromise() {
2137  let mdAlgName = "SHA256"; // Digest algorithm name.
2138  let message = "mdTestMessgae"; // Data to be digested.
2139  let md = cryptoFramework.createMd(mdAlgName);
2140  ;
2141  console.info("[Promise]: Md algName is: " + md.algName);
2142  // If the data volume is small, you can use update() once to pass in all data. There is no limit on the length of the input parameter.
2143  let promiseMdUpdate = md.update({ data: stringToUint8Array(message) });
2144  promiseMdUpdate.then(() => {
2145    // Call digest() to return the result.
2146    let PromiseMdDigest = md.digest();
2147    return PromiseMdDigest;
2148  }).then(digestOutput => {
2149    let mdOutput = digestOutput;
2150    console.info("[Promise]: MD result: " + mdOutput.data);
2151    let mdLen = md.getMdLength();
2152    console.info("[Promise]: MD len: " + mdLen);
2153  }).catch((error: BusinessError) => {
2154    console.error("[Promise]: error: " + error.message);
2155  });
2156}
2157
2158// Generate a digest in callback mode.
2159function doMdByCallback() {
2160  let mdAlgName = "SHA256"; // Digest algorithm name.
2161  let message = "mdTestMessgae"; // Data to be digested.
2162  let md = cryptoFramework.createMd(mdAlgName);
2163  console.info("[Callback]: Md algName is: " + md.algName);
2164  // If the data volume is small, you can use update() once to pass in all data. There is no limit on the length of the input parameter.
2165  md.update({ data: stringToUint8Array(message) }, (err,) => {
2166    if (err) {
2167      console.error("[Callback]: err: " + err.code);
2168    }
2169    md.digest((err1, digestOutput) => {
2170      if (err1) {
2171        console.error("[Callback]: err: " + err1.code);
2172      } else {
2173        let mdOutput = digestOutput;
2174        console.info("[Callback]: MD result: " + mdOutput.data);
2175        let mdLen = md.getMdLength();
2176        console.info("[Callback]: MD len: " + mdLen);
2177      }
2178    });
2179  });
2180}
2181```
2182
2183### Generating a Digest by Segment
2184
21851. Use **createMd()** to create an **Md** instance.
21862. Use **update()** multiple times to pass in by segment.
21873. Use **digest()** to compute a digest.
21884. Obtain the digest algorithm and length of the digest generated.
2189
2190```ts
2191import cryptoFramework from '@ohos.security.cryptoFramework';
2192import { BusinessError } from '@ohos.base';
2193
2194// Convert strings in plaintext into byte streams.
2195function stringToUint8Array(str: string) {
2196  let arr = new Uint8Array(str.length);
2197  for (let i = 0, j = str.length; i < j; ++i) {
2198    arr[i] = str.charCodeAt(i);
2199  }
2200  return arr;
2201}
2202
2203// Generate a digest by segment in promise mode.
2204async function doLoopMdPromise() {
2205  let mdAlgName = "SHA256"; // Digest algorithm name.
2206  let md = cryptoFramework.createMd(mdAlgName);
2207  ;
2208  console.info("[Promise]: Md algName is: " + md.algName);
2209  let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; // Assume that the message is of 43 bytes.
2210  let messageArr: number[] = [];
2211  let updateLength = 20; // For example, pass in 20 bytes in each update().
2212
2213  for (let i = 0; i <= messageText.length; i++) {
2214    if ((i % updateLength == 0 || i == messageText.length) && messageArr.length != 0) {
2215      let message = new Uint8Array(messageArr);
2216      let messageBlob: cryptoFramework.DataBlob = { data: message };
2217      // Use await to process the update() in the for() loop.
2218      try {
2219        await md.update(messageBlob); // Use update() to process data by segment.
2220      } catch (error) {
2221        let e: BusinessError = error as BusinessError;
2222        console.error(`await update error, ${e.code}, ${e.message}`);
2223        return;
2224      }
2225      messageArr = [];
2226    }
2227    // Pad messageArr based on the segment length.
2228    if (i < messageText.length) {
2229      messageArr.push(messageText.charCodeAt(i));
2230    }
2231  }
2232  let PromiseMdDigest = md.digest();
2233  PromiseMdDigest.then(digestOutput => {
2234    let mdOutput = digestOutput;
2235    console.info("[Promise]: MD result: " + mdOutput.data);
2236    let mdLen = md.getMdLength();
2237    console.info("[Promise]: MD len: " + mdLen);
2238  }).catch((error: BusinessError) => {
2239    console.error("[Promise]: error: " + error.message);
2240  });
2241}
2242```
2243
2244## HMAC
2245
2246### When to Use
2247
2248A hash-based message authentication code (HMAC) can be used to verify both the integrity and authenticity of a message using a shared secret.
2249
2250Typical MAC operations involve the following:
2251
22521. Create a **Mac** instance.
22532. Initialize the **Mac** instance, add one or more segments of data for generating a MAC, and generate a MAC.
22543. Obtain the algorithm and length of a MAC.
2255
2256### Available APIs
2257
2258For details about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
2259
2260| Instance         | API                                                      | Description                                               |
2261| --------------- | ------------------------------------------------------------ | --------------------------------------------------- |
2262| cryptoFramework | function createMac(algName : string) : Mac;                  | Creates a **Mac** instance.                |
2263| Mac             | init(key : SymKey, callback : AsyncCallback\<void>) : void; | Initializes the **Mac** instance. This API uses an asynchronous callback to return the result.|
2264| Mac             | init(key : SymKey) : Promise\<void>;                        | Initializes the **Mac** instance. This API uses a promise to return the result. |
2265| 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.      |
2266| Mac             | update(input : DataBlob) : Promise\<void>;                  | Updates the data for the MAC operation. This API uses a promise to return the result.       |
2267| Mac             | doFinal(callback : AsyncCallback\<DataBlob>) : void;        | Finalizes the MAC operation to generate a MAC. This API uses an asynchronous callback to return the result.                |
2268| Mac             | doFinal() : Promise\<DataBlob>;                             | Finalizes the MAC operation to generate a MAC. This API uses a promise to return the result.                 |
2269| Mac             | getMacLength() : number;                                     | Obtains the length of the MAC based on the specified algorithm.              |
2270| Mac             | readonly algName : string;                                   | Obtains the digest algorithm.                           |
2271
2272### Generating an HMAC
2273
22741. Use **createMac()** to create a **Mac** instance.
22752. Use **init()** to initialize the **Mac** instance with the symmetric key passed in.
22763. Use **update()** to pass in the data for computing an HMAC.
22774. Use **doFinal()** to generate an HMAC.
22785. Obtain the algorithm and length of the HMAC.
2279
2280```ts
2281import cryptoFramework from '@ohos.security.cryptoFramework';
2282import { BusinessError } from '@ohos.base';
2283
2284// Convert strings in plaintext into byte streams.
2285function stringToUint8Array(str: string) {
2286  let arr = new Uint8Array(str.length);
2287  for (let i = 0, j = str.length; i < j; ++i) {
2288    arr[i] = str.charCodeAt(i);
2289  }
2290  return arr;
2291}
2292
2293// Generate an HMAC in promise mode.
2294function doHmacByPromise() {
2295  let macAlgName = "SHA256"; // Digest algorithm name.
2296  let message = "hmacTestMessgae"; // Data used to generate an HMAC.
2297  let mac = cryptoFramework.createMac(macAlgName);
2298  console.info("[Promise]: Mac algName is: " + mac.algName);
2299  let KeyBlob: cryptoFramework.DataBlob = {
2300    // 128-bit key
2301    data: stringToUint8Array("12345678abcdefgh")
2302  }
2303  let symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
2304  // Convert the binary data into a key.
2305  let promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
2306  promiseConvertKey.then(symKey => {
2307    let promiseMacInit = mac.init(symKey);
2308    return promiseMacInit;
2309  })
2310    .then(() => {
2311      // If the data volume is small, you can use update() once to pass in all data. There is no limit on the length of the input parameter.
2312      let promiseMacUpdate = mac.update({ data: stringToUint8Array(message) });
2313      return promiseMacUpdate;
2314    })
2315    .then(() => {
2316      let PromiseMacDoFinal = mac.doFinal();
2317      return PromiseMacDoFinal;
2318    })
2319    .then(output => {
2320      let macOutput = output;
2321      console.info("[Promise]: HMAC result: " + macOutput.data);
2322      let macLen = mac.getMacLength();
2323      console.info("[Promise]: MAC len: " + macLen);
2324    })
2325    .catch((error: BusinessError) => {
2326      console.error("[Promise]: error: " + error.message);
2327    });
2328}
2329
2330// Generate an HMAC in callback mode.
2331function doHmacByCallback() {
2332  let macAlgName = "SHA256"; // Digest algorithm name.
2333  let message = "hmacTestMessgae"; // Data used to generate an HMAC.
2334  let mac = cryptoFramework.createMac(macAlgName);
2335  console.info("[Promise]: Mac algName is: " + mac.algName);
2336  let KeyBlob: cryptoFramework.DataBlob = {
2337    // 128-bit key
2338    data: stringToUint8Array("12345678abcdefgh")
2339  }
2340  let symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
2341  // Convert the binary data into a key.
2342  symKeyGenerator.convertKey(KeyBlob, (err, symKey) => {
2343    if (err) {
2344      console.error("[Callback]: err: " + err.code);
2345    }
2346    mac.init(symKey, (err1,) => {
2347      if (err1) {
2348        console.error("[Callback]: err: " + err1.code);
2349      }
2350      // If the data volume is small, you can use update() once to pass in all data. There is no limit on the length of the input parameter.
2351      mac.update({ data: stringToUint8Array(message) }, (err2,) => {
2352        if (err2) {
2353          console.error("[Callback]: err: " + err2.code);
2354        }
2355        mac.doFinal((err3, output) => {
2356          if (err3) {
2357            console.error("[Callback]: err: " + err3.code);
2358          } else {
2359            let macOutput = output;
2360            console.error("[Callback]: HMAC result: " + macOutput.data);
2361            let macLen = mac.getMacLength();
2362            console.error("[Callback]: MAC len: " + macLen);
2363          }
2364        });
2365      });
2366    });
2367  });
2368}
2369```
2370
2371### Generating an HMAC by Segment
2372
2373Generate an HMAC by segment.
2374
23751. Use **createMac()** to create a **Mac** instance.
23762. Use **init()** to initialize the **Mac** instance with the symmetric key passed in.
23773. Call **update()** multiple times to pass in data by segment.
23784. Use **doFinal()** to generate an HMAC.
23795. Obtain the algorithm and length of the HMAC.
2380
2381```ts
2382import cryptoFramework from '@ohos.security.cryptoFramework';
2383import { BusinessError } from '@ohos.base';
2384
2385function stringToUint8Array(str: string) {
2386  let arr = new Uint8Array(str.length);
2387  for (let i = 0, j = str.length; i < j; ++i) {
2388    arr[i] = str.charCodeAt(i);
2389  }
2390  return arr;
2391}
2392
2393function doLoopHmacPromise() {
2394  let macAlgName = "SHA256"; // Digest algorithm name.
2395  let mac = cryptoFramework.createMac(macAlgName);
2396  console.info("[Promise]: Mac algName is: " + mac.algName);
2397  let KeyBlob: cryptoFramework.DataBlob = {
2398    // 128-bit key
2399    data: stringToUint8Array("12345678abcdefgh")
2400  }
2401  let messageText = "aaaaa.....bbbbb.....ccccc.....ddddd.....eee"; // Assume that the message is of 43 bytes.
2402  let updateLength = 20; // For example, pass in 20 bytes in each update().
2403  let symKeyGenerator = cryptoFramework.createSymKeyGenerator("AES128");
2404  // Convert the binary data into a key.
2405  let promiseConvertKey = symKeyGenerator.convertKey(KeyBlob);
2406  promiseConvertKey.then((symKey: cryptoFramework.SymKey): Promise<void> => {
2407    let promiseMacInit = mac.init(symKey);
2408    return promiseMacInit;
2409  })
2410    .then(async () => {
2411      let messageArr: number[] = [];
2412      for (let i = 0; i <= messageText.length; i++) {
2413        if ((i % updateLength == 0 || i == messageText.length) && messageArr.length != 0) {
2414          let message = new Uint8Array(messageArr);
2415          let messageBlob: cryptoFramework.DataBlob = { data: message };
2416          // Use await to process the update() in the for() loop.
2417          try {
2418            await mac.update(messageBlob); // Invoke update() multiple times.
2419          } catch (error) {
2420            let e: BusinessError = error as BusinessError;
2421            console.error(`await update error, ${e.code}, ${e.message}`);
2422            return;
2423          }
2424          messageArr = [];
2425        }
2426        // Pad messageArr based on the segment length.
2427        if (i < messageText.length) {
2428          messageArr.push(messageText.charCodeAt(i));
2429        }
2430      }
2431      return;
2432    })
2433    .then(() => {
2434      let PromiseMacDoFinal = mac.doFinal();
2435      return PromiseMacDoFinal;
2436    })
2437    .then(output => {
2438      let macOutput = output;
2439      console.log("[Promise]: HMAC result: " + macOutput.data);
2440      let macLen = mac.getMacLength();
2441      console.log("[Promise]: MAC len: " + macLen);
2442    })
2443    .catch((error: BusinessError) => {
2444      console.error("[Promise]: error: " + error.message);
2445    });
2446}
2447```
2448
2449## Random Number
2450
2451### When to Use
2452
2453Typical random number operations involve the following:
2454
24551. Create a **Random** instance and specify the length (in bytes) of the random number to generate a secure random number of the specified length (ranging from **1** to **INT_MAX**).
24562. Set a seed based on the random number generated.
2457
2458### Available APIs
2459
2460For more information about the APIs, see [Crypto Framework](../reference/apis/js-apis-cryptoFramework.md).
2461
2462| Instance         | API                                                      | Description                                      |
2463| --------------- | ------------------------------------------------------------ | ------------------------------------------ |
2464| cryptoFramework | function createRandom() : Random;                            | Creates a **Random** instance.                      |
2465| Random          | generateRandom(len : number, callback: AsyncCallback\<DataBlob>) : void; | Generates a random number. This API uses an asynchronous callback to return the result.|
2466| Random          | generateRandom(len : number) : Promise\<DataBlob>;           | Generates a random number. This API uses a promise to return the result. |
2467| Random          | generateRandomSync(len: number): DataBlob;                   | Generates a random number of the specified length synchronously.              |
2468| Random          | setSeed(seed : DataBlob) : void;                             | Sets a seed.                    |
2469
2470### How to Develop
2471
24721. Use **createRandom()** to create a **Random** instance.
24732. Use **generateRandom()** to generate a random number of the given length.
24743. Use **setSeed()** to set a seed.
2475
2476```ts
2477import cryptoFramework from '@ohos.security.cryptoFramework';
2478import { BusinessError } from '@ohos.base';
2479
2480// Generate a random number in promise mode.
2481function doRandByPromise() {
2482  let rand = cryptoFramework.createRandom();
2483  let len = 4; // Generate a 4-byte random number.
2484  let promiseGenerateRand = rand.generateRandom(len);
2485  promiseGenerateRand.then(randData => {
2486    console.info("[Promise]: rand result: " + randData.data);
2487    try {
2488      rand.setSeed(randData);
2489    } catch (error) {
2490      let e: BusinessError = error as BusinessError;
2491      console.error(`setSeed failed, ${e.code}, ${e.message}`);
2492    }
2493  }).catch((error: BusinessError) => {
2494    console.error("[Promise]: error: " + error.message);
2495  });
2496}
2497
2498// Generate a random number in callback mode.
2499function doRandByCallback() {
2500  let rand = cryptoFramework.createRandom();
2501  let len = 4; // Generate a 4-byte random number.
2502  rand.generateRandom(len, (err, randData) => {
2503    if (err) {
2504      console.error("[Callback]: err: " + err.code);
2505    } else {
2506      console.info("[Callback]: generate random result: " + randData.data);
2507      try {
2508        rand.setSeed(randData);
2509      } catch (error) {
2510        let e: BusinessError = error as BusinessError;
2511        console.error(`setSeed failed, ${e.code}, ${e.message}`);
2512      }
2513    }
2514  });
2515}
2516
2517// Generate a random number synchronously.
2518function doRandBySync() {
2519  let rand = cryptoFramework.createRandom();
2520  let len = 24; // Generate a 24-byte random number.
2521  try {
2522    let randData = rand.generateRandomSync(len);
2523    if (randData != null) {
2524      console.info("[Sync]: rand result: " + randData.data);
2525    } else {
2526      console.error("[Sync]: get rand result fail!");
2527    }
2528  } catch (error) {
2529    let e: BusinessError = error as BusinessError;
2530    console.error(`do rand failed, ${e.code}, ${e.message}`);
2531  }
2532}
2533```
2534