verify function cannot work
Posted: Sun Aug 27, 2017 11:25 pm
I encountered a problem when testing the sign/verify function of the java card. I can successfully upload and install the applet. And the signature generation can also work fine as well. But the verify function never works. It always threw error INVALID_SIGNATURE. Could anyone help me find where I made mistake? Thanks a lot.
Code: Select all
package signECC;
import javacard.framework.*;
import javacard.security.*;
public class SignECC extends Applet {
final static byte SignECC_CLA = (byte)0xB0;
final static byte INS_GEN_KEY_PAIR = (byte)0x10;
final static byte INS_SIGN = (byte)0x20;
final static byte INS_VERIFY = (byte)0x30;
final static short INVALID_SIGNATURE = 0x6A80;
final static short PROBLEM_KEY_GENERATION = 0x6A81;
final static short e1 = 0x0007;
final static short e2 = 0x0006;
final static short e3 = 0x0003;
final static byte[] data = {(byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67, (byte)0x89,
(byte)0xAB, (byte)0xCD, (byte)0xEF};
final static short k = 0x0002;
static byte[] a = {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01};
static byte[] b = {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01};
static byte[] pointG = {(byte)0x04, (byte)0x02, (byte)0xFE, (byte)0x13, (byte)0xC0,
(byte)0x53, (byte)0x7B, (byte)0xBC, (byte)0x11, (byte)0xAC,
(byte)0xAA, (byte)0x07, (byte)0xD7, (byte)0x93, (byte)0xDE,
(byte)0x4E, (byte)0x6D, (byte)0x5E, (byte)0x5C, (byte)0x94,
(byte)0xEE, (byte)0xE8, (byte)0x02, (byte)0x89, (byte)0x07,
(byte)0x0F, (byte)0xB0, (byte)0x5D, (byte)0x38, (byte)0xFF,
(byte)0x58, (byte)0x32, (byte)0x1F, (byte)0x2E, (byte)0x80,
(byte)0x05, (byte)0x36, (byte)0xD5, (byte)0x38, (byte)0xCC,
(byte)0xDA, (byte)0xA3, (byte)0xD9};
static byte[] r = {(byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x02, (byte)0x01, (byte)0x08, (byte)0xA2, (byte)0xE0,
(byte)0xCC, (byte)0x0D, (byte)0x99, (byte)0xF8, (byte)0xA5, (byte)0xEF};
private KeyPair keyPair;
private ECPrivateKey ECPrivate;
private ECPublicKey ECPublic;
private Signature signature;
short signLength;
private byte[] output;
private SignECC (byte[] bArray,short bOffset,byte bLength){
signature = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
output = JCSystem.makeTransientByteArray((short)100, JCSystem.CLEAR_ON_DESELECT);
register();
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SignECC(bArray, bOffset, bLength);
}
public boolean select() {
return true;
}
public void deselect(){
}
public void process(APDU apdu) {
byte[] buffer = apdu.getBuffer();
if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte)(0xA4)) )
return;
if (buffer[ISO7816.OFFSET_CLA] != SignECC_CLA)
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
switch (buffer[ISO7816.OFFSET_INS]) {
case INS_GEN_KEY_PAIR:
generate_KeyPair(apdu);
return;
case INS_SIGN:
generate_signature(apdu);
return;
case INS_VERIFY:
verify_signature(apdu);
return;
default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void generate_KeyPair(APDU apdu){
keyPair = new KeyPair(KeyPair.ALG_EC_F2M, KeyBuilder.LENGTH_EC_F2M_163);
keyPair.genKeyPair();
ECPublic = (ECPublicKey)keyPair.getPublic();
ECPrivate = (ECPrivateKey)keyPair.getPrivate();
ECPublic.setFieldF2M(e1, e2, e3);
ECPublic.setA(a, (short)0, (short)21);
ECPublic.setB(b, (short)0, (short)21);
ECPublic.setG(pointG, (short)0, (short)43);
ECPublic.setK(k);
ECPublic.setR(r, (short)0, (short)21);
ECPrivate.setFieldF2M(e1, e2, e3);
ECPrivate.setA(a, (short)0, (short)21);
ECPrivate.setB(b, (short)0, (short)21);
ECPrivate.setG(pointG, (short)0, (short)43);
ECPrivate.setK(k);
ECPrivate.setR(r, (short)0, (short)21);
}
private void generate_signature(APDU apdu){
byte[] buffer = apdu.getBuffer();
signature.init(ECPrivate, Signature.MODE_SIGN);
signLength = signature.sign(data, (short)0, (short)8, output,(short)0);
short size = Util.arrayCopy(output, (short)0, buffer, (short)0, signLength);
apdu.setOutgoingAndSend((short)0, size);
}
private void verify_signature(APDU apdu){
signature.init(ECPublic, Signature.MODE_VERIFY);
boolean result = signature.verify(data, (short)0, (short)8, output, (short)0, signLength);
if(result == false)
ISOException.throwIt(INVALID_SIGNATURE);
}
}