I have been stuck in a long time. I am using Hybrid Crypto library in React Native to encrypt the message. Both public and private key are in PEM format.
let crypt = new Crypt({rsaStandard: 'RSA-OAEP'});
let encrypted = crypt.encrypt(publicKey, "This is a message");
return JSON.parse(encrypted).cipher;
This is the code I use to decrypt in Java. I followed this tutorial to read private key from pem file using bouncycastle library.
String str = "M2vFz/28sWhwAK4rGmnFAPRORRTlfa+XYpHFWQsi0bo=";
Security.addProvider(new BouncyCastleProvider());
KeyFactory factory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = generatePrivateKey(factory, RESOURCES_DIR + "private-key.pem");
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptOut = decryptCipher.doFinal(Base64.getDecoder().decode(str));
System.out.println(new String(decryptOut));
I've been trying many ways, the private key works fine when I decrypt in React but with Java I keep getting javax.crypto.BadPaddingException: Decryption error.
Updated Solution
Because I'm using hybrid crypto so it will include RSA + AES
Flow in frondend: Using AES key to encrypt text => Using public RSA key to encrypt AES key. Then you send everything you need to decrypt (encrypted AES key, Iv, and cipher text)
let crypt = new Crypt({rsaStandard: 'RSAES-PKCS1-V1_5',aesIvSize: 16});
let encrypted = crypt.encrypt(publicKey, str);
const encryptedObj = JSON.parse(encrypted);
return Object.values(encryptedObj.keys)[0] + ',' + encryptedObj.iv + ',' + encryptedObj.cipher;
Flow in java: Using RSA private key to decrypt AES key => Using AES key + Iv to decrypt cipher text
PrivateKey privateKey = generatePrivateKey();
Cipher decryptCipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] keyb = decryptCipher.doFinal(Base64.getDecoder().decode(AESkey));
SecretKeySpec skey = new SecretKeySpec(keyb, "AES");
IvParameterSpecivspec = new IvParameterSpec(Base64.getDecoder().decode(iv));
decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, skey, ivspec);
byte[] decryptOut = decryptCipher.doFinal(Base64.getDecoder().decode(cipherText));
return new String(decryptOut);