1

I am facing some issues when decrypt a RSA Base64 encoded string in java.RSA encrypted string is made by c#.Net.

Actually, I created a public and private key by using java. Then I exchanged the public key to .Net Team. They encrypted a string by using the public key with the use of RSACryptoServiceProvider class.

.Net code:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize);
rsa.FromXmlString(publicKey);
.......
.......
byte[] encryptedBytes = rsa.Encrypt(tempBytes, false);
Array.Reverse(encryptedBytes);
stringBuilder.Append(Convert.ToBase64String(encryptedBytes));

Java decrypt Code:

   public static void doDecrypt( BigInteger  modules, BigInteger  d , String encrypted )
    {
            try {
                    byte[] decodedBytes = Base64.decodeBase64( encrypted );
                    KeyFactory factory = KeyFactory.getInstance("RSA");
                    Cipher cipher = Cipher.getInstance("RSA");

                    RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, d);
                    PrivateKey privKey = factory.generatePrivate(privSpec);

                    cipher.init(Cipher.DECRYPT_MODE, privKey);
                    byte[] decrypted = cipher.doFinal(decodedBytes) ;
                    System.out.println("decrypted: " + new String(decrypted));
            }
            catch (Exception e) {
                    e.printStackTrace();
            }

    }

While decrypting the string, It says the following error.

javax.crypto.BadPaddingException: Data must start with zero
   at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
   at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
   at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
   at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
   at javax.crypto.Cipher.doFinal(DashoA13*..)

then , I tried with

 Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");

But, It gives junk characters, Which I could not relate to my desired plain text. I think , Somewhere I am missing to do something.Please guide me on this.

sat
  • 14,589
  • 7
  • 46
  • 65
  • 3
    For a start, the C# code does `Array.Reverse(encryptedBytes);` but the Java code does not reverse the reversed bytes back. Solution: remove `Array.Reverse(encryptedBytes);` from the C# code. – dtb Sep 22 '12 at 12:59
  • Will it works , if perform the reverse once again in java before doing the decrypt. – sat Sep 22 '12 at 13:29
  • You should use the same padding mode for both, namely OAEP. – CodesInChaos Sep 22 '12 at 17:28
  • @sat I think that reversing the bytes should do the trick. Even though RSA is a number calculation, the RSA output should always be big endian (otherwise it would not be compatible), so I don't know why your colleagues called `Array.Reverse` on it. – Maarten Bodewes Sep 22 '12 at 22:45

1 Answers1

-1
rsa.Encrypt(tempBytes, false)

leads to PKCS#1 v1.5 padding. So you must use the same on the java side. Try to use

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

I think the windows API uses ECB by default, but you might want to try other modes like CBC or CFB too.

Peter F.
  • 111
  • 1
  • 7
  • What he should do is switch to OAEP for both. PKCS#1 v1.5 padding for encryption should be avoided. – CodesInChaos Sep 22 '12 at 17:27
  • And those block cipher chaining modes don't make much sense with RSA. .net encrypts a single block with RSA. – CodesInChaos Sep 22 '12 at 17:31
  • Right. But depending on the block length a multi-block operation might be needed. – Peter F. Sep 22 '12 at 17:48
  • In that case one would use a hybrid cryptosystem. Most chaining modes like CBC can't even work with RSA, since RSA has smaller input than output due to padding. – CodesInChaos Sep 22 '12 at 17:50
  • I agree with you about the OAEP. But he uses PKCS padding on the .NET side, and I just wanted to point him to the appropriate setting in java. About that CBC stuff, I must say that I have no idea how microsoft actually implemented the RSA stuff, and also how sun did with java. So trying different settings would surely not hurt. – Peter F. Sep 22 '12 at 17:57
  • 1
    @PeterF that should be `"PKCS1Padding"`, obviously. `"PKCS5Padding"` is used for 8 byte block ciphers. – Maarten Bodewes Sep 22 '12 at 22:43
  • -1 because this uncorrected answer led the lazy OP to copy and paste his way to another error [here](http://stackoverflow.com/questions/12577185/how-to-solve-the-nosuchalgorithmexception-in-java) – President James K. Polk Sep 26 '12 at 01:11