1# Encryption and Decryption with an SM2 Asymmetric Key Pair
2
3
4For details about the algorithm specifications, see [SM2](crypto-asym-encrypt-decrypt-spec.md#sm2).
5
6
7**Encryption**
8
9
101. Use [cryptoFramework.createAsyKeyGenerator](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygenerator) and [AsyKeyGenerator.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-1) to create a 256-bit SM2 asymmetric key pair (**KeyPair**). The **KeyPair** object includes a public key (**PubKey**) and a private key (**PriKey**).
11
12   In addition to the example in this topic, [SM2](crypto-asym-key-generation-conversion-spec.md#sm2) and [Randomly Generating an Asymmetric Key Pair](crypto-generate-asym-key-pair-randomly.md) may help you better understand how to generate an SM2 asymmetric key pair. Note that the input parameters in the reference documents may be different from those in the example below.
13
142. Use [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) with the string parameter **'SM2_256|SM3'** to create a **Cipher** instance. The key type is **SM2_256**, and the MD algorithm is **SM3**.
15
163. Use [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In **Cipher.init**, set **opMode** to **CryptoMode.ENCRYPT_MODE** (encryption) and **key** to **KeyPair.PubKey** (the key used for encryption).
17
18   No encryption parameter is required for asymmetric key pairs. Therefore, pass in **null** in **params**.
19
204. Use [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to pass in the plaintext and encrypt it.
21
22   - The output of **Cipher.doFinal** may be **null**. To avoid exceptions, always check whether the result is **null** before accessing specific data.
23   - If a large amount of data is to be encrypted, you can call **Cipher.doFinal** multiple times to pass in the data by segment.
24
25
26**Decryption**
27
28
291. If SM2 is used, the **Cipher** instance cannot be initialized repeatedly. Use [cryptoFramework.createCipher](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreatecipher) to create a new **Cipher** instance.
30
312. Use [Cipher.init](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#init-1) to initialize the **Cipher** instance. In **Cipher.init**, set **opMode** to **CryptoMode.DECRYPT_MODE** (decryption) and **key** to **KeyPair.PriKey** (the key used for decryption). If SM2 is used, no decryption parameter is required. Therefore, pass in **null** in **params**.
32
333. Use [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to pass in the ciphertext and decrypt it.
34
35
36- Example (using asynchronous APIs):
37
38  ```ts
39  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
40  import { buffer } from '@kit.ArkTS';
41
42  // Encrypt the message.
43  async function encryptMessagePromise(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
44    let cipher = cryptoFramework.createCipher('SM2_256|SM3');
45    await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
46    let encryptData = await cipher.doFinal(plainText);
47    return encryptData;
48  }
49  // Decrypt the message.
50  async function decryptMessagePromise(privateKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {
51    let decoder = cryptoFramework.createCipher('SM2_256|SM3');
52    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null);
53    let decryptData = await decoder.doFinal(cipherText);
54    return decryptData;
55  }
56  // Generate an SM2 key pair.
57  async function genKeyPairByData(pubKeyData: Uint8Array, priKeyData: Uint8Array) {
58    let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
59    let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData };
60    let sm2Generator = cryptoFramework.createAsyKeyGenerator('SM2_256');
61    let keyPair = await sm2Generator.convertKey(pubKeyBlob, priKeyBlob);
62    console.info('convertKey success');
63    return keyPair;
64  }
65  async function main() {
66    let pkData = 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]);
67    let skData = 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]);
68    let keyPair = await genKeyPairByData(pkData, skData);
69    let pubKey = keyPair.pubKey;
70    let priKey = keyPair.priKey;
71    let message = 'This is a test';
72    // Decode the string into a Uint8Array in UTF-8 format.
73    let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
74    let encryptText = await encryptMessagePromise(pubKey, plainText);
75    let decryptText = await decryptMessagePromise(priKey, encryptText);
76    if (plainText.data.toString() === decryptText.data.toString()) {
77      console.info('decrypt ok');
78      // Encode the Uint8Array into a string in UTF-8 format.
79      let messageDecrypted = buffer.from(decryptText.data).toString('utf-8');
80      console.info('decrypted result string:' + messageDecrypted);
81    } else {
82      console.error('decrypt failed');
83    }
84  }
85  ```
86
87- Example (using synchronous APIs):
88
89  ```ts
90  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
91  import { buffer } from '@kit.ArkTS';
92
93  // Encrypt the message.
94  function encryptMessage(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
95    let cipher = cryptoFramework.createCipher('SM2_256|SM3');
96    cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
97    let encryptData = cipher.doFinalSync(plainText);
98    return encryptData;
99  }
100  // Decrypt the message.
101  function decryptMessage(privateKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {
102    let decoder = cryptoFramework.createCipher('SM2_256|SM3');
103    decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, privateKey, null);
104    let decryptData = decoder.doFinalSync(cipherText);
105    return decryptData;
106  }
107  // Generate an SM2 key pair.
108  function genKeyPairByData(pubKeyData: Uint8Array, priKeyData: Uint8Array) {
109    let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
110    let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData };
111    let sm2Generator = cryptoFramework.createAsyKeyGenerator('SM2_256');
112    let keyPair = sm2Generator.convertKeySync(pubKeyBlob, priKeyBlob);
113    console.info('convertKeySync success');
114    return keyPair;
115  }
116  function main() {
117    let pkData = 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]);
118    let skData = 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]);
119    let keyPair = genKeyPairByData(pkData, skData);
120    let pubKey = keyPair.pubKey;
121    let priKey = keyPair.priKey;
122    let message = 'This is a test';
123    // Decode the string into a Uint8Array in UTF-8 format.
124    let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
125    let encryptText = encryptMessage(pubKey, plainText);
126    let decryptText = decryptMessage(priKey, encryptText);
127    if (plainText.data.toString() === decryptText.data.toString()) {
128      console.info('decrypt ok');
129      // Encode the Uint8Array into a string in UTF-8 format.
130      let messageDecrypted = buffer.from(decryptText.data).toString('utf-8');
131      console.info('decrypted result string:' + messageDecrypted);
132    } else {
133      console.error('decrypt failed');
134    }
135  }
136  ```
137