Question

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

Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top