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.