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