Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Padding error when using RSA Encryption in C# and Decryption in Java

Currently I am receiving the following error when using Java to decrypt a Base64 encoded RSA encrypted string that was made in C#:

javax.crypto.BadPaddingException: Not PKCS#1 block type 2 or Zero padding

The setup process between the exchange from .NET and Java is done by creating a private key in the .NET key store then from the PEM file extracted, created use keytool to create a JKS version with the private key. Java loads the already created JKS and decodes the Base64 string into a byte array and then uses the private key to decrypt.

Here is the code that I have in C# that creates the encrypted string:

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);
}

Here is the code that I have in Java that decrypts the inputted string:

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));
}

Does anyone see a step missing or where the padding or item needs to be changed? I have done hours of reading on this site and others but haven't really found a concrete solution.

You're help is vastly appreciated.

Thanks. -Matt

like image 546
Matt Shaver Avatar asked Aug 19 '09 23:08

Matt Shaver


1 Answers

I had exactely the same problem and I finally find the solution!

I was stubborn using PKCS1Padding but I didn't manage to make it work.

The best result I got using "rsa.Encrypt(baIn, false)" on the C# side and "RSA/NONE/NoPadding" on the Java side was this kind of string : "☻?o+_>??5?l0Q*???*?R▲???♀7..." followed by my decrypted string. So in a way it got decrypted but since there is no padding specified, the data is shifted. So I tried all the paddings available in bouncycastle but I would alway get errors such as "block incorrect size" or "data hash wrong".

So I decided to start trying OAEP paddings and I finally managed to get it working by using "rsa.Encrypt(baIn, true)" on the C# side and "RSA/NONE/OAEPWithSHA1AndMGF1Padding" on the java side!

It worked for me, I hope it will work for you too! If it doesn't work make sure you're using the right key, very often the problem comes from the key.

like image 150
Migs Avatar answered Oct 06 '22 09:10

Migs