I'm trying to encrypt data in my react app using RSA encryption then decrypt it on my backend. For the front end I want to use JSEencrypt, and in the backend I want to use the built-in crypto library. I know the encryption aspect is working as I tested it with https://travistidwell.com/jsencrypt/demo/ and it worked fine. But I can't decrypt it. I always get an error:
Error during decryption (probably incorrect key).
Original error: Error: error:02000079:rsa routines::oaep decoding error
This is my frontend code:
var encrypt = new JSEncrypt();
var publicKey = `
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
gwQco1KRMDSmXSMkDwIDAQAB
-----END PUBLIC KEY-----`;
encrypt.setPublicKey(publicKey);
const objectToEncrypt = {product_name: 'Testing', product_price: 10 };
const jsonString = JSON.stringify(objectToEncrypt);
var encrypted = encrypt.encrypt(jsonString);
It's then sent through an API. This is my backend code:
const crypto = require('crypto');
var privateKey = `
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876
-----END RSA PRIVATE KEY-----`
const encryptedData = req.body.encrypted;
const decryptedData = crypto.privateDecrypt({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256', // Adjust hash function if needed
}, Buffer.from(encryptedData, 'base64'));
console.log('Decrypted data:', decryptedData.toString('utf8'));
JSEncrypt uses PKCS#1 v1.5 padding and does not support OAEP (s. issue #84). Since OAEP is used in the crypto-code, the implementations are incompatible.
Fix: Use PKCS#1 v1.5 padding in the crypto-code as well (i.e. apply crypto.constants.RSA_PKCS1_PADDING
):
...
const decryptedData = crypto.privateDecrypt({
key: privateKey,
padding: crypto.constants.RSA_PKCS1_PADDING, // Fix, apply PKCS#1 v1.5 padding
oaepHash: 'sha256', // Ignored for PKCS#1 v1.5, can be removed
}, Buffer.from(encryptedData, 'base64'));
...
or use another library than JSEncrypt which also supports OAEP.