We are facing an issue while trying to Encrypt data in Android and Decrypt it in a WCF Service. The Android code to encrypt data is as follows:
try{
String strModulus = "tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=";
String strExponent = "AQAB";
byte[] modulusBytes = Base64.decode(strModulus, Base64.DEFAULT);
byte[] exponentBytes = Base64.decode(strExponent, Base64.DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA/ECB/PKCS1Padding");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] plainBytes = new String("Manchester United").getBytes("UTF-8");
byte[] cipherData = cipher.doFinal(plainBytes);
encryptedString = Base64.encodeToString(cipherData, Base64.DEFAULT);
}
catch(Exception e){
Log.e("Error", e.toString());
}
return encryptedString;
The same code in Java:
try{
String strModulus = "tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZHG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=";
String strExponent = "AQAB";
byte[] modulusBytes = DatatypeConverter.parseBase64Binary("tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=");
byte[] exponentBytes = DatatypeConverter.parseBase64Binary("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("Manchester United").getBytes("UTF-8");
byte[] cipherData = cipher.doFinal(plainBytes);
//String encryptedString = Base64.encodeToString(cipherData, Base64.NO_PADDING);
String encryptedString = DatatypeConverter.printBase64Binary(cipherData);
String encryptedData = encryptedString;
}
catch(Exception e){
}
}
WCF Service:
public string Decrypt() { const int PROVIDER_RSA_FULL = 1; const string CONTAINER_NAME = "Tracker"; CspParameters cspParams; cspParams = new CspParameters(PROVIDER_RSA_FULL); cspParams.KeyContainerName = CONTAINER_NAME; RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams); rsa1.FromXmlString("<RSAKeyValue><Modulus>tr82UfeGetV7yBKcOPjFTWs7pHqqr/5YKKWMUZ/HG4HnCmWrZsOhuR1FBnMZ/g2YiosoSlu0zd7Ukz9lX7wv2RLfWXfMvZYGpAAvfYWwzbyQ2i1q+tKE/thgKNscoSRellDD+uJcYn1H4hnaudVyYJH9miVhOKhKlExMzw8an6U=</Modulus><Exponent>AQAB</Exponent><P>6e0nv7EBFBugtpoB+ozpg1J4js8E+DVyWCuBsERBPzqu4H7Z/oeLIRSC8Gi5GZgrCpBf3EvyIluM7rzaIfNThQ==</P><Q>x/29X9ns1WcXC42IJjLDjscz5ygdVh79dm8B2tQVbqwyhDsQ6OIOQdu5+eHf4hUMoTrM9KkS2F6FGlLXuaOFoQ==</Q><DP>kTS2LMaJ/dpce5zDx6w6s1q5HSSiWBSNIu/2s9zah448yXvUg6vNkD40PVk0NRAA/7C44H2AExWzOOqfmN17JQ==</DP><DQ>xtAx9drQPWnpl/uQUOEAVa0kpPTVDStrr9Q1FNTnpYkcAyYw7kLkB4anAIoSpk9kqdeprsNxz5VPXtbiTFMKYQ==</DQ><InverseQ>O0594NMjnjSp+/NAa1kQxoQNzn1qqq+p1Zb+kT3/jRc/0d7ZnqSSpxFMXfxx3yZkNAOPDOdbckPQbRZ13RKBHg==</InverseQ><D>bjVEagwvkrZaTt9CTW1hd3362weLFlX6DpE/3R3RcrpVfkSwKGpEhqGrNeeGPlsuqiaf5rAFir4eTqrF1QVliKsU4XE0RyzP5lHGc7dlX4DOHMjs2R9nNWv8QOTPoaRuLrLGorqBXlw/jQPxFI6gQzkIIjzuf//lDVnFam3dw4E=</D></RSAKeyValue>"); string data2Decrypt = "LyVNDhkdJ5jNgwZDiVZ1R0lmd10AQgqNDFHh2vJB1676eg8wj0MOdTyChAGrvEjha0uXg+f/aNBAc4+/LFbCgsA1e+O3wnXr27sXznGJ9G15avZzQHG4JWUS42MXBahAkcJ80pcihTbL9edfQCkEuj9RzQ/zFJyDEMssfd/EPDM="; byte[] encyrptedBytes = Convert.FromBase64String(data2Decrypt); byte[] plain = rsa1.Decrypt(encyrptedBytes, false); string decryptedString = System.Text.Encoding.UTF8.GetString(plain); }
Original Data : 'Manchester United'
The strange thing is that if I encrypt a string with the Java code it can be decrypted at the WCF service end, however, if it is encrypted using the above Android code, the decryption provides the error: "The data to be decrypted exceeds the maximum for this modulus of 128 bytes".
On debugging, I realized that the byte[] cipherData
is not the same for Android and Java. All the previous values happen to be in sync. This generates different Encrypted Strings in Java and Android.
My question is why does this happen? Is there a silly mistake? Is there a way to work around it? Or something else that can be done in Android to get the 'Cipher Data' right?
Any help will be appreciated.