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