Mohsen Afshin Mohsen Afshin - 1 year ago 167
Android Question

Java equivalent of .NET RSACryptoServiceProvider with SHA-1

I have the following data signing code in C#

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

string PrivateKeyText = "<RSAKeyValue><Modulus>....</D></RSAKeyValue>";


string data = "my data";

byte[] SignedByteData = rsa.SignData(Encoding.UTF8.GetBytes(data), new SHA1CryptoServiceProvider());

and I want reproduce the same code in Java (Android):

String modulusElem = "...";
String expElem = "...";

byte[] expBytes = Base64.decode(expElem, Base64.DEFAULT);
byte[] modulusBytes = Base64.decode(modulusElem, Base64.DEFAULT);

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

try {
KeyFactory factory = KeyFactory.getInstance("RSA");

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

String data = "my data";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] hashedData = md.digest(data.getBytes("UTF-8"));

RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(modulus, exponent);

PublicKey publicKey = factory.generatePublic(pubSpec);

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] SignedByteData = cipher.doFinal(hashedData);

} catch (Exception e){


But I get mismatched output byte arrays. Where am I wrong and What should be the transformation used in

Answer Source

Use Signature.getInstance("SHA1withRSA"). Encryption is not the same as signature generation. Different padding mechanisms for one.

Update by Afshin

Complete solution. Note the use of the private exponent, ie <D>, rather the public <Exponent>

String modulusElem = "...";
String dElem = "...";

byte[] modulusBytes = Base64.decode(modulusElem, Base64.DEFAULT);
byte[] dBytes = Base64.decode(dElem, Base64.DEFAULT);

BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger d = new BigInteger(1, dBytes);

String data = "my data";            

try {
        Signature signature = Signature.getInstance("SHA1withRSA");

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

        RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, d);

        PrivateKey privateKey = factory.generatePrivate(privateKeySpec);



        byte[] SignedByteData = signature.sign();

} catch(Exception e) {
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download