2

I have used RSA Assymetric Key Encryption Algorithm in C# program (I have mentioned below) and I have to encrypt data through a java program. I want my java program to generate same encrypted key as like result of C# program.

Public Key:

<RSAKeyValue>
<Modulus>zgfXY1oUe4nyndX4qtobP1BMxtJ1/rfKU5csdAcWrSVu6ZaEAX3rL3cWnaSLzX4E1BNjSP9pjge6TH7UoaWqOQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>

C# Encryption Programme:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

 rsa.FromXmlString(PublicKey); // read public key XML defined above

byte[] buffer = rsa.Encrypt(Encoding.UTF8.GetBytes(strToEncrypt), false);

string encryptedStr = HttpUtility.UrlEncode(buffer);// byteConverterGetString;

Java Encryption Programme:

byte[] modulusBytes = Base64.decode("zgfXY1oUe4nyndX4qtobP1BMxtJ1/rfKU5csdAcWrSVu6ZaEAX3rL3cWnaSLzX4E1BNjSP9pjge6TH7UoaWqOQ==");
byte[] exponentBytes = Base64.decode("AQAB");

BigInteger modulus = new BigInteger(1, modulusBytes );               
BigInteger exponent = new BigInteger(1, exponentBytes);

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);

KeyFactory fact = KeyFactory.getInstance("RSA");

PublicKey pubKey = fact.generatePublic(rsaPubKey);

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

cipher.init(Cipher.ENCRYPT_MODE, pubKey);

byte[] plainBytes = new String("Admin123").getBytes("UTF-8");

byte[] cipherData = cipher.doFinal( plainBytes );

String encryptedString = Base64.encodeBytes(cipherData);

System.out.println(URLEncoder.encode(encryptedString));

I tried above java program but it gives me result like:

o%2Bgw7%2BXhYxA9ltDV5zERsF4DyXgMTc%2Fgx82wRtT1xfR3suY0XBJLadp7bXjmSX7CplDVdoQyH05Jpqgkd%2B1G4A%3D%3D

and C# program generates like

%23E%03%c2%10)%40E%bf%7b%f9%11%87c0%12q%b9w%ba%2c%98%b4%b1%96%bc%ee%c5_%c9t%1e'%e71%85%b68t%00%3a%b7%d9%fb%a1%18%ba%10%b4%c3c%e1'*%3b%f6D%e2%cc6%82%80%f2%a6

so can anyone help me to correct my java program.. thanks

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254

2 Answers2

1

It seems to me that you're URL encoding two different things:

  • In Java you're encoding a Base64 encoded string, whereas
  • In C# you're doing it on a byte array

The result of these two different approaches will not be the same. Perhaps you should encode new String( cipherData ) in the Java part - or just compare the two byte[] arrays before encoding?

Cheers,

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
  • Agreed, start by printing the buffers as hex (or something simple) and then move into URL encoding (or whatever) once you're convinced the answer is correct. – Duncan Jones Oct 17 '12 at 07:20
  • Thanks for reply But when i print byte array of both program then it display like below so i think there may be problem in encryption code Java Byte generated: [-70 60 36 -37 -51 -118 37 3 55 -113 -52 -49 106 -111 35 -128 20 -120 56 -23 38 92 22 117 121 -5 44 -12 -101 19 -60 92 76 23 -33 -81 -21 -117 -92 -21 44 95 61 -100 -107 -124 -90 -123 -65 30 2 102 -1 62 -128 75 -116 111 -115 117 85 36 70 63] – Yogesh Patel Oct 17 '12 at 08:42
  • Continue: C# byte generated: 180 122 109 115 113 67 227 152 86 176 214 242 197 96 187 232 233 39 95 146 234 169 174 229 175 115 167 175 34 125 50 64 204 15 15 171 51 197 122 221 194 115 22 210 126 173 127 95 92 142 5 78 56 176 237 225 208 159 47 6 32 46 236 243 – Yogesh Patel Oct 17 '12 at 08:45
  • Ensure that it is the same `byte[]`'s you are encrypting as well; i.e. compare the `strToEncrypt` and `plainBytes` after UTF-8 encoding. – Anders R. Bystrup Oct 17 '12 at 08:57
  • I printed that byte array of `strtoEncrypt` and `plainBytes` prints byte array as like below [65 100 109 105 110 49 50 51] – Yogesh Patel Oct 17 '12 at 09:15
  • `Byte` array is negative in java Encryption. is there something problem of encryption code in java. because C# code is perfect and it works fine... – Yogesh Patel Oct 17 '12 at 09:21
  • 1
    A Java byte is signed (i.e. [-128..127]) whereas the C# version is unsigned. Cf. http://stackoverflow.com/questions/6223102/is-java-byte-the-same-as-c-sharp-byte -- thus (depending on the concrete crypto implementations) you may be encrypting two different cleartexts. – Anders R. Bystrup Oct 17 '12 at 10:12
  • thanks dude, you are right.java doesnot support unsigned byte so this problem occures. if i put java byte array to C# and then test, it works fine. so what can i do in java to do this.. – Yogesh Patel Oct 17 '12 at 12:17
  • I don't really see any possibility on the Java side. Do you know for a fact that the C# version is the "Ground truth"? Really, I think the crypto algorithm shouldn't worry about the signed/unsigned-ness of the cleartext, so this does surprise me quite a bit... – Anders R. Bystrup Oct 17 '12 at 12:41
  • Oh another thing: Are you absolutely sure that both Java and C# uses the same padding mechanism? I seem to recall that there are different versions of PKCS#1 which differ in the padding size? – Anders R. Bystrup Oct 17 '12 at 12:46
  • Both Java and C# uses PKCS1 algorithm for padding.They use same padding because my C# generate encypted bytes are similiar as java encrypted byte. In java I use `byte & 0xFF` to make it unsigned and if i give that byte array to C# then C# generates same encrypted text. So i have to play around that unsigned byte array in java.. – Yogesh Patel Oct 17 '12 at 13:07
  • @YogeshPatel: The PKCS#1 padding includes random bytes, so the results are supposed to be different. Your expectation that the cipher will be the same is incorrect. – President James K. Polk Oct 17 '12 at 16:47
  • Thank you so much to All guys ....Problem solved. From Cipher bytes , I have done below code as like C# does in java `for(int i=0;i – Yogesh Patel Oct 19 '12 at 08:55
0

You are URLencoding diferent objects, just try this code:

byte[] modulusBytes = Base64.decode("zgfXY1oUe4nyndX4qtobP1BMxtJ1/rfKU5csdAcWrSVu6ZaEAX3rL3cWnaSLzX4E1BNjSP9pjge6TH7UoaWqOQ==");
byte[] exponentBytes = Base64.decode("AQAB");

BigInteger modulus = new BigInteger(1, modulusBytes );               
BigInteger exponent = new BigInteger(1, exponentBytes);

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);

KeyFactory fact = KeyFactory.getInstance("RSA");

PublicKey pubKey = fact.generatePublic(rsaPubKey);

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

cipher.init(Cipher.ENCRYPT_MODE, pubKey);

byte[] plainBytes = new String("Admin123").getBytes("UTF-8");

byte[] cipherData = cipher.doFinal( plainBytes );

String string = new String(cipherData);

System.out.println(URLEncoder.encode(string,"UTF-8"));
DiogoPinheiro
  • 147
  • 1
  • 16