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