Hello,
I'm signing some data on a .net-based smartcard and trying to verify that signature in a java environment - but without success.
Smartcard (c#):
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);
// In a different method, rsaParams.Exponent and rsaParams.Modulus are set
rsaProvider.ImportParameters(rsaParams); // Here I'm importing the key
SHA1 sha1 = SHA1.Create();
byte[] signature = rsaProvider.SignData(data, sha1);
Client (Java):
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(rsaPublicKey); // initiate the signature with public key
sig.update(data); // update signature with the data that was signed by the card
sig.verify(signedData); // Test card signature - this always returns false
I then tried to create the signature on the Java client (for testing) - and it turns out that the signature created on the Java client is different from the one created on the smartcard. I created it like this:
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(rsaPrivateKey);
sig.update(data);
locallySigned = sig.sign();
Now I understand that the signature is something like the hash of (passed data + the used algorithm). Is it possible that the implementations are not compatible here? Am I missing something else? Thanks!
PS: Yes, I verified that both input and output are transferred correctly from/to the card, that the key parameters are set and that input/output are exactly the same.
Edit: Key Generation in Java:
// Create a key-pair and install the private key on the card
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair keyPair = keyGen.genKeyPair();
privateKey = (RSAPrivateKey)keyPair.getPrivate();
publicKey = (RSAPublicKey)keyPair.getPublic();
and then I'm setting exp and mod of the private key on the card.