Can someone give me a small advice on how to make a signature with javacard and verify it? I guess I am doing something wrong with the signature generation and verification:
...
SignatureMessageRecovery sig;
...
private Cardlet(byte[] bArray, short bOffset, byte bLength) {
/* Generate our RSA key */
keyPair = new KeyPair(KeyPair.ALG_RSA, (short) 512);
keyPair.genKeyPair();
/* signature buffer is 64 + 2 (offset + length) */
sigBuff = JCSystem.makeTransientByteArray((short) (SIG_LENGTH + 2), JCSystem.CLEAR_ON_DESELECT);
sig = (SignatureMessageRecovery) Signature.getInstance(Signature.ALG_RSA_SHA_ISO9796_MR, false);
}
...
private void insCryptoSigne(APDU apdu) {
byte[] buffer = apdu.getBuffer();
short bytesRead = apdu.setIncomingAndReceive();
short[] m1Data = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT);
sigLen = sig.sign(buffer, ISO7816.OFFSET_CDATA, bytesRead, sigBuff, (short) 0, m1Data, (short) 0);
// set m1Length into sigBuff array
sigBuff[sigLen] = (byte) ((short) (m1Data[(short) 0] & ((short) 0xFF00)) >> ((short) 8));
sigBuff[(short) (sigLen + 1)] = (byte) (m1Data[(short) 0] & ((short) 0x00FF));
apdu.setOutgoing();
apdu.setOutgoingLength((short) (sigLen + 2));// The extra 2 bytes for
apdu.sendBytesLong(sigBuff, (short) 0, (short) (sigLen + 2));
}
ON Java side I already have gotten the public key saved it in a file localy as a X509Certificate. Pretty sure they are the same as the modulus and exponent seem the same in both, certificate and card.
FileInputStream certis = new FileInputStream(cert);
X509Certificate c1 = new X509Certificate(certis);
...
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] testsig = new byte[64];
System.arraycopy(raw_signature,0, testsig, 0, 64);
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
signature.initVerify(c1.getPublicKey());
System.out.println(c1.getPublicKey());
System.out.println(signature);
System.out.println(file_data.length+":> "+new String(file_data));
signature.update(file_data);
System.out.println("VERIFY > "+signature.verify(testsig)+" <");
The result is false :(
Thanks and Regards Turi
For starters, you are using two separate signature functions. The older ISO9796 is rather different from the PKCS#1 signature format which is used if you specify "SHA1withRSA"
on the Java side. Do you really need message recovery? It's mostly used for card verifiable certificates nowadays ( if it is used).
Simply use Signature
and ALG_RSA_SHA_PKCS1
instead of SignatureMessageRecovery
and ALG_RSA_SHA_ISO9796_MR
on the Java Card side.
If you want message recovery you may have to use the Bouncy Castle library at the Java side (and even in Bouncy it is a bit tricky to get it working correctly).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.