Actualmente estoy recibiendo el siguiente error cuando se utiliza Java para descifrar una base 64 codificado RSA cadena cifrada que se hizo en C#:error de relleno cuando se utiliza RSA cifrado en C# y descifrado en Java
javax.crypto.BadPaddingException : No PKCS # 1 cuadra de tipo 2 o de relleno cero
el proceso de configuración entre el intercambio de, el uso de .NET y Java se realiza mediante la creación de una clave privada en el almacén de claves .NET luego desde el archivo PEM extraída creado keytool para crear una versión de JKS con la clave privada. Java carga el JKS ya creado y decodifica la cadena Base64 en una matriz de bytes y luego usa la clave privada para descifrar.
Aquí está el código que tengo en C# que crea la cadena cifrada:
public string Encrypt(string value) {
byte[] baIn = null;
byte[] baRet = null;
string keyContainerName = "test";
CspParameters cp = new CspParameters();
cp.Flags = CspProviderFlags.UseMachineKeyStore;
cp.KeyContainerName = keyContainerName;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
// Convert the input string to a byte array
baIn = UnicodeEncoding.Unicode.GetBytes(value);
// Encrypt
baRet = rsa.Encrypt(baIn, false);
// Convert the encrypted byte array to a base64 string
return Convert.ToBase64String(baRet);
}
Aquí está el código que tengo en Java que descifra la cadena introducida:
public void decrypt(String base64String) {
String keyStorePath = "C:\Key.keystore";
String storepass = "1234";
String keypass = "abcd";
byte[] data = Base64.decode(base64String);
byte[] cipherData = null;
keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream(keyStorePath), storepass.toCharArray());
RSAPrivateKey privateRSAKey = (RSAPrivateKey) keystore.getKey(alias, keypass.toCharArray());
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateRSAKey);
cipherData = cipher.doFinal(data);
System.out.println(new String(cipherData));
}
¿Hay alguien ver un paso que falta o donde el relleno o elemento necesita ser cambiado? He hecho horas de lectura en este sitio y otros, pero realmente no he encontrado una solución concreta.
Su ayuda es muy apreciada.
Gracias. -Matt
¿Dónde está el relleno especificado en el código C#? ¿Cómo sabe que OAEP (que es PKCS # 1 ver.2) no se está utilizando durante el cifrado? – erickson
Primero, aísle el cifrado y la codificación en probelmas por separado. Es decir. valide que el byte de Java decodificado [] es idéntico al byte de C# original []. entonces puedes preguntar si es un problema de RSA o de Base64. Como dijo Erickson, probablemente sea la diferencia en el PKCS predeterminado entre C# y las libs de Java. –
@erickson - el segundo parámetro del método .NET Encrypt() selecciona el relleno - true especifica OAEP y falso (usado en el ejemplo) especifica PKCS # 1 ver 1.5. –