I am developping an Android app, and I need to use java Signature
class for data authentication.
On each Android device, I can sign data and verify its signature. However, given a definite chunk of data to sign, a definite modulus, a definite private exponent and a definite public exponent, the outputs of my signatures are different, depending on devices. I did try with bunch of devices, and I obtain the same signatures for Android 3.2 and 3.2.1, but a differents for an Android 2.2.x device.
I compute these signature from constant fields that I generated previously using a KeyFactory
with RSA in a java project. The keysize is 2048bit.
Here is a quote of the code that I use to invoque Signature and Verification.
public byte[] signData(byte[] data, PrivateKey privateKey) throws ... {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}
public boolean verifyData(byte[] data, byte[] sigBytes, PublicKey publicKey) throws ... {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sigBytes);
}
If I am not mistaking, the signature using SHA256 with RSA is deterministic. Then how can I explain such a behaviour? Another interesting question, how could I make that work cross-devices, i.e. the signatures would be same, no mather which device I use?
Thank you in advance, Franck!
Yes, SHA256withRSA
is completely deterministic.
In theory you could be affected by a bug (see an example) in an old modified BouncyCastle library version found on one of the Android versions. Such a bug might be eliminated if you used SHA512withRSA
instead, well, at least the referenced one would be.
However, before you start digging into the hash algorithm, check close to home.
Maybe you have obtained your byte array through a call to String.getBytes
. This call depends on the default platform encoding which is different between Android 2.2 and Android 2.3. This implies that while your strings are the same in both cases, the byte arrays might not be.
To get encoding under control, and make your code platform independent, specify encoding as a parameter:
plainText.getBytes("UTF-8")
Failing this, there are a few more tactics to get a platform independent implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With