Búsqueda de sitios web

typescript - Cifrar RSA usando JSEncrypt y descifrar usando BouncyCastle (Java)


Esto podría ser un duplicado de esta pregunta ya respondida, pero no parece que pueda obtener los mismos resultados. Espero obtener algo de orientación aquí.

JSEncrypt (cliente)

let encrypt = new Encrypt.JSEncrypt();
encrypt.setPublicKey(this.publicKey);  // retrieved from server
encrypt.encrypt(password);

BouncyCastle (servidor) - generación de clave RSA

KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024);
KeyPair pair = generator.generateKeyPair();
PublicKey pubKey = pair.getPublic();
PrivateKey privKey = pair.getPrivate();

// returned to client
String publicKeyStr = new String(Base64.encodeBase64(pubKey.getEncoded()));
String privateKeyStr = new String(Base64.encodeBase64(privKey.getEncoded()));

BouncyCastle (servidor) - Descifrado

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// org.apache.commons.codec.binary.Hex

byte[] cipherText = cipher.doFinal(Hex.decodeHex(encrypted.toCharArray()));
decrypted = new String(cipherText, BaseConstant.ENC_UTF8);

Error

org.apache.commons.codec.DecoderException: Carácter hexadecimal ilegal I en el índice 0 en org.apache.commons.codec.binary.Hex.toDigit(Hex.java:178) en org.apache.commons.codec.binary.Hex.decodeHex(Hex.java:89)

Una cosa que noté es la longitud del texto encriptado por JSEncrypt, que es 172, mientras que la encriptación en el lado del servidor produce 256.

La pregunta respondida mencionó usar RSA/None/PKCS1Padding, lo cual ya había configurado. ¿Qué más podría estar pasando por alto?

Respuesta #1

El error ocurre en el método Hex.decodeHex(), lo que significa que tus datos no son una cadena codificada en Hex.

El método JSEncrypt.encrypt() devuelve los datos cifrados en Base64 (en lugar de una cadena Hex). Para poder descifrarlos, debes decodificarlos desde el formato base64.

Así que en lugar de:

byte[] cipherText = cipher.doFinal(Hex.decodeHex(encrypted.toCharArray()));

Haz esto:

byte[] cipherText = cipher.doFinal(Base64.decodeBase64(encrypted.toCharArray()));

Respuesta #2

También puedes resolver este problema solo desde el lado del cliente. Mira el código a continuación:

let encrypt = new Encrypt.JSEncrypt(); 
encrypt.setPublicKey(this.publicKey);
encrypt.getKey().encrypt(password);

Solo agrega getKey() después de encrypt. ¡Funcionó para mí! Encripté mi contraseña en una cadena Hex usando este enfoque.

Artículos relacionados