1# Encryption and Decryption with an RSA Asymmetric Key Pair (PKCS1_OAEP)
2
3
4For details about the algorithm specifications, see [RSA](crypto-asym-encrypt-decrypt-spec.md#rsa).
5
6
7**Encryption**
8
9
101. Use [cryptoFramework.createAsyKeyGeneratorBySpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#cryptoframeworkcreateasykeygeneratorbyspec10) and [AsyKeyGeneratorBySpec.generateKeyPair](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#generatekeypair-3) to generate an RSA asymmetric key pair (**KeyPair**) based on the specified key parameters.
11
12   In addition to the example in this topic, [RSA](crypto-asym-key-generation-conversion-spec.md#rsa) and [Generating an Asymmetric Key Pair Based on Key Parameters](crypto-generate-asym-key-pair-from-key-spec.md) may help you better understand how to generate an RSA 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 **'RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1'** to create a **Cipher** instance. The key type is **RSA2048**, padding mode is **PKCS1_OAEP**, MD algorithm is **SHA256**, and mask digest algorithm is **MGF1_SHA1**.
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.setCipherSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#setcipherspec10) to set the parameter **pSource** for **PKCS1_OAEP** before **Cipher.doFinal** is called. You can use [Cipher.getCipherSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getcipherspec10) to obtain OAEP-related parameters.
21
225. Use [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to pass in the plaintext and encrypt it.
23
24
25**Decryption**
26
27
281. If RSA 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.
29
302. 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). When PKCS1 mode is used, pass in **null** in **params**.
31
323. Use [Cipher.setCipherSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#setcipherspec10) to set the parameter **pSource** for **PKCS1_OAEP** before **Cipher.doFinal** is called. The value of **pSource** must be the same as that set in encryption. You can use [Cipher.getCipherSpec](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#getcipherspec10) to obtain OAEP-related parameters.
33
344. Use [Cipher.doFinal](../../reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md#dofinal-1) to pass in the ciphertext and decrypt it.
35
36
37- Example (using asynchronous APIs):
38
39  ```ts
40  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
41  import { buffer } from '@kit.ArkTS';
42  // Construct the RSA key pair parameter based on the key pair specifications.
43  function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
44    let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
45      n: nIn,
46      algName: "RSA",
47      specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
48    };
49    let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
50      params: rsaCommSpec,
51      sk: dIn,
52      pk: eIn,
53      algName: "RSA",
54      specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
55    };
56    return rsaKeyPairSpec;
57  }
58  // Generate the RSA2048 key pair parameter.
59  function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
60    let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
61    let eIn = BigInt("0x010001");
62    let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
63    return genRsaKeyPairSpec(nIn, eIn, dIn);
64  }
65  async function rsaUseSpecDecryptOAEPPromise() {
66    let plan = "This is a test";
67    // Generate the RSA key pair parameter (Rsa2048KeyPairSpec) object.
68    let rsaKeyPairSpec = genRsa2048KeyPairSpec();
69    // Generate an RSA key pair based on the RSA key pair parameter.
70    let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
71    let cipher = cryptoFramework.createCipher("RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1");
72    let decoder = cryptoFramework.createCipher("RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1");
73    // Set pSource, which defines the encoding input P filled by OAEP.
74    let pSource = new Uint8Array([1, 2, 3, 4]);
75    let input: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan, 'utf-8').buffer) };
76    // Generate a key pair.
77    let keyPair = await rsaGeneratorSpec.generateKeyPair();
78    // Initialize the encryption operation.
79    await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
80    // Set and obtain the Cipher specifications after the initialization.
81    cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
82    let retP = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
83    // Check whether the obtained PSource is the same as the PSource set.
84    if (retP.toString() != pSource.toString()) {
85      console.error("error init pSource" + retP);
86    } else {
87      console.info("pSource changed ==" + retP);
88    }
89    // Obtain other OAEP parameters.
90    let md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
91    console.info("md == " + md);
92    let mgf = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
93    console.info("mgf == " + mgf);
94    let mgf1Md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
95    console.info("mgf1Md == " + mgf1Md);
96    let cipherDataBlob = await cipher.doFinal(input);
97    // 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.
98    decoder.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
99    retP = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
100    // Check whether the obtained PSource is the same as the PSource set.
101    if (retP.toString() != pSource.toString()) {
102      console.error("error init pSource" + retP);
103    } else {
104      console.info("pSource changed ==" + retP);
105    }
106    // Obtain other OAEP parameters.
107    md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
108    console.info("md == " + md);
109    mgf = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
110    console.info("mgf == " + mgf);
111    mgf1Md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
112    console.info("mgf1Md == " + mgf1Md);
113    // Initialize the decryption operation.
114    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
115    let decodeData = await decoder.doFinal(cipherDataBlob);
116    // The decryption is successful.
117    if (decodeData.data.toString() === input.data.toString()) {
118      console.info("oaep decrypt success");
119    } else {
120      console.error("oaep decrypt fail");
121    }
122  }
123  ```
124
125- Example (using synchronous APIs):
126
127  ```ts
128  import { cryptoFramework } from '@kit.CryptoArchitectureKit';
129  import { buffer } from '@kit.ArkTS';
130  // Construct the RSA key pair parameter based on the key pair specifications.
131  function genRsaKeyPairSpec(nIn: bigint, eIn: bigint, dIn: bigint) {
132    let rsaCommSpec: cryptoFramework.RSACommonParamsSpec = {
133      n: nIn,
134      algName: "RSA",
135      specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC
136    };
137    let rsaKeyPairSpec: cryptoFramework.RSAKeyPairSpec = {
138      params: rsaCommSpec,
139      sk: dIn,
140      pk: eIn,
141      algName: "RSA",
142      specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC
143    };
144    return rsaKeyPairSpec;
145  }
146  // Generate the RSA2048 key pair parameter.
147  function genRsa2048KeyPairSpec(): cryptoFramework.RSAKeyPairSpec {
148    let nIn = BigInt("0x9260d0750ae117eee55c3f3deaba74917521a262ee76007cdf8a56755ad73a1598a1408410a01434c3f5bc54a88b57fa19fc4328daea0750a4c44e88cff3b2382621b80f670464433e4336e6d003e8cd65bff211da144b88291c2259a00a72b711c116ef7686e8fee34e4d933c868187bdc26f7be071493c86f7a5941c3510806ad67b0f94d88f5cf5c02a092821d8626e8932b65c5bd8c92049c210932b7afa7ac59c0e886ae5c1edb00d8ce2c57633db26bd6639bff73cee82be9275c402b4cf2a4388da8cf8c64eefe1c5a0f5ab8057c39fa5c0589c3e253f0960332300f94bea44877b588e1edbde97cf2360727a09b775262d7ee552b3319b9266f05a25");
149    let eIn = BigInt("0x010001");
150    let dIn = BigInt("0x6a7df2ca63ead4dda191d614b6b385e0d9056a3d6d5cfe07db1daabee022db08212d97613d3328e0267c9dd23d787abde2afcb306aeb7dfce69246cc73f5c87fdf06030179a2114b767db1f083ff841c025d7dc00cd82435b9a90f695369e94df23d2ce458bc3b3283ad8bba2b8fa1ba62e2dce9accff3799aae7c840016f3ba8e0048c0b6cc4339af7161003a5beb864a0164b2c1c9237b64bc87556994351b27506c33d4bcdfce0f9c491a7d6b0628c7c852be4f0a9c3132b2ed3a2c8881e9aab07e20e17deb074691be677776a78b5c502e05d9bdde72126b3738695e2dd1a0a98a14247c65d8a7ee79432a092cb0721a12df798e44f7cfce0c498147a9b1");
151    return genRsaKeyPairSpec(nIn, eIn, dIn);
152  }
153  function main() {
154    let plan = "This is a test";
155    // Generate the RSA key pair parameter (Rsa2048KeyPairSpec) object.
156    let rsaKeyPairSpec = genRsa2048KeyPairSpec();
157    // Generate an RSA key pair based on the RSA key pair parameter.
158    let rsaGeneratorSpec = cryptoFramework.createAsyKeyGeneratorBySpec(rsaKeyPairSpec);
159    let cipher = cryptoFramework.createCipher("RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1");
160    let decoder = cryptoFramework.createCipher("RSA2048|PKCS1_OAEP|SHA256|MGF1_SHA1");
161    // Set pSource, which defines the encoding input P filled by OAEP.
162    let pSource = new Uint8Array([1, 2, 3, 4]);
163    let input: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(plan, 'utf-8').buffer) };
164    // Generate a key pair.
165    let keyPair = rsaGeneratorSpec.generateKeyPairSync();
166    // Initialize the encryption operation.
167    cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
168    // Set and obtain the Cipher specifications after the initialization.
169    cipher.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
170    let retP = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
171    // Check whether the obtained PSource is the same as the PSource set.
172    if (retP.toString() != pSource.toString()) {
173      console.error("error init pSource" + retP);
174    } else {
175      console.info("pSource changed ==" + retP);
176    }
177    // Obtain other OAEP parameters.
178    let md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
179    console.info("md == " + md);
180    let mgf = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
181    console.info("mgf == " + mgf);
182    let mgf1Md = cipher.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
183    console.info("mgf1Md == " + mgf1Md);
184    let cipherDataBlob = cipher.doFinalSync(input);
185    // 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.
186    decoder.setCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR, pSource);
187    retP = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_PSRC_UINT8ARR);
188    // Check whether the obtained PSource is the same as the PSource set.
189    if (retP.toString() != pSource.toString()) {
190      console.error("error init pSource" + retP);
191    } else {
192      console.info("pSource changed ==" + retP);
193    }
194    // Obtain other OAEP parameters.
195    md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MD_NAME_STR);
196    console.info("md == " + md);
197    mgf = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF_NAME_STR);
198    console.info("mgf == " + mgf);
199    mgf1Md = decoder.getCipherSpec(cryptoFramework.CipherSpecItem.OAEP_MGF1_MD_STR);
200    console.info("mgf1Md == " + mgf1Md);
201    // Initialize the decryption operation.
202    decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
203    let decodeData = decoder.doFinalSync(cipherDataBlob);
204    // The decryption is successful.
205    if (decodeData.data.toString() === input.data.toString()) {
206      console.info("oaep decrypt success");
207    } else {
208      console.error("oaep decrypt fail");
209    }
210  }
211  ```
212