He estado atrapado en mucho tiempo. Estoy usando la biblioteca Hybrid Crypto en React Native para cifrar el mensaje. Tanto la clave pública como la privada están en formato PEM.
let crypt = new Crypt({rsaStandard: 'RSA-OAEP'}); let encrypted = crypt.encrypt(publicKey, "This is a message"); return JSON.parse(encrypted).cipher;
Este es el código que uso para descifrar en Java. Seguí este tutorial para leer la clave privada del archivo pem usando la biblioteca bouncycastle.
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));
Lo he estado intentando de muchas maneras, la clave privada funciona bien cuando descifro en React pero con Java sigo recibiendo javax.crypto.BadPaddingException: error de descifrado.
Solución actualizada
Debido a que estoy usando criptografía híbrida, incluirá RSA + AES
Flujo de entrada: Uso de la clave AES para cifrar texto => Uso de la clave RSA pública para cifrar la clave AES. Luego, envía todo lo que necesita para descifrar (clave AES cifrada, Iv y texto cifrado)
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;
Flujo en Java: Uso de la clave privada RSA para descifrar la clave AES => Uso de la clave AES + Iv para descifrar el texto cifrado
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);