Am facing an issue in KeyAgreement.generatesecret() method while trying to generate a shared secret key.
There are two applets. One applet 'ECCShareKey Applet ' has the implementation of ECC key pair generation and shared secret key generation. And this applet implements a shareable interface 'ECCSharekeyShareableInterface' which in turn extends Shareable class.
Other applet 'ECCShareKeyClient Applet' is a client applet which access the shareable methods of 'ECCShareKey applet'.
Am using secp192k1 for ECC key pair generation.
The issue here is after generating key pair when i try to generate secret key from Client applet it throws Crypto exception - ILLEGAL VALUE. But when i execute the same through the ECCShareKey it works absolutely fine.
The error is only during when trying to generate secret key throgh client applet. All crypto objects have been granted externalAccess.
Kindly, let me know if am following anything wrong.
Code: Select all
public interface ECCShareKeyShareableInterface extends Shareable{
public void GenerateECDHKeyPair();
public short GenerateSharedSecretKey() ;
public short getCardPublicKeyPointW(byte[] PublicKeyPointW);
}
Code: Select all
public class ECCShareKey extends Applet implements ECCShareKeyShareableInterface {
protected static final byte ECDH_Parameter_P[] = {
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFE,(byte)0xFF,(byte)0xFF,(byte)0xFC,(byte)0x2F
};
protected static final byte ECDH_Parameter_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)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00
};
protected static final byte ECDH_Parameter_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)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x07
};
protected static final byte ECDH_Parameter_G[] = {
(byte)0x04, (byte)0x79,(byte)0xBE,(byte)0x66,(byte)0x7E,(byte)0xF9,(byte)0xDC,(byte)0xBB,(byte)0xAC,
(byte)0x55,(byte)0xA0,(byte)0x62,(byte)0x95,(byte)0xCE,(byte)0x87,(byte)0x0B,(byte)0x07,
(byte)0x02,(byte)0x9B,(byte)0xFC,(byte)0xDB,(byte)0x2D,(byte)0xCE,(byte)0x28,(byte)0xD9,
(byte)0x59,(byte)0xF2,(byte)0x81,(byte)0x5B,(byte)0x16,(byte)0xF8,(byte)0x17,(byte)0x98,
(byte)0x48,(byte)0x3A,(byte)0xDA,(byte)0x77,(byte)0x26,(byte)0xA3,(byte)0xC4,(byte)0x65,
(byte)0x5D,(byte)0xA4,(byte)0xFB,(byte)0xFC,(byte)0x0E,(byte)0x11,(byte)0x08,(byte)0xA8,
(byte)0xFD,(byte)0x17,(byte)0xB4,(byte)0x48,(byte)0xA6,(byte)0x85,(byte)0x54,(byte)0x19,
(byte)0x9C,(byte)0x47,(byte)0xD0,(byte)0x8F,(byte)0xFB,(byte)0x10,(byte)0xD4,(byte)0xB8
};
protected static final byte ECDH_Parameter_R[] = {
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFE,
(byte)0xBA,(byte)0xAE,(byte)0xDC,(byte)0xE6,(byte)0xAF,(byte)0x48,(byte)0xA0,(byte)0x3B,
(byte)0xBF,(byte)0xD2,(byte)0x5E,(byte)0x8C,(byte)0xD0,(byte)0x36,(byte)0x41,(byte)0x41
};
protected static final byte ECDH_Parameter_K = (byte)0x01;
private KeyPair KeyPairECDH2;
private ECPublicKey PublicKeyECDH2;
private ECPrivateKey PrivateKeyECDH2;
private KeyPair KeyPairECDH1;
private ECPublicKey PublicKeyECDH1;
private ECPrivateKey PrivateKeyECDH1;
private KeyAgreement KeyAgreementECDH;
private short ECDHSecretKeyLength;
private byte[] PublicKeyPointW;
short DEFAULT_OFFSET = (short) 0;
short RANDOM_DATA_LENGTH = (short) 16;
public ECCShareKey() {
KeyAgreementECDH = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH, true);
PublicKeyPointW = new byte[100];
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
// GP-compliant JavaCard applet registration
new ECCShareKey().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x04:
GenerateECDHKeyPair();
break;
case (byte)0x05:
GenerateSharedSecretKey();
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
public void GenerateECDHKeyPair() {
try {
PrivateKeyECDH1 = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
KeyBuilder.LENGTH_EC_FP_192, false);
PrivateKeyECDH1 = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
KeyBuilder.LENGTH_EC_FP_256, false);
PrivateKeyECDH1.setFieldFP(ECDH_Parameter_P, (short) 0, (short) ECDH_Parameter_P.length);
PrivateKeyECDH1.setA(ECDH_Parameter_A, (short) 0, (short) ECDH_Parameter_A.length);
PrivateKeyECDH1.setB(ECDH_Parameter_B, (short) 0, (short) ECDH_Parameter_B.length);
PrivateKeyECDH1.setG(ECDH_Parameter_G, (short) 0, (short) ECDH_Parameter_G.length);
PrivateKeyECDH1.setK(ECDH_Parameter_K);
PrivateKeyECDH1.setR(ECDH_Parameter_R, (short) 0, (short) ECDH_Parameter_R.length);
PublicKeyECDH1 = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
KeyBuilder.LENGTH_EC_FP_192, false);
PublicKeyECDH1 = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
KeyBuilder.LENGTH_EC_FP_256, false);
PublicKeyECDH1.setFieldFP(ECDH_Parameter_P, (short) 0, (short) ECDH_Parameter_P.length);
PublicKeyECDH1.setA(ECDH_Parameter_A, (short) 0, (short) ECDH_Parameter_A.length);
PublicKeyECDH1.setB(ECDH_Parameter_B, (short) 0, (short) ECDH_Parameter_B.length);
PublicKeyECDH1.setG(ECDH_Parameter_G, (short) 0, (short) ECDH_Parameter_G.length);
PublicKeyECDH1.setK(ECDH_Parameter_K);
PublicKeyECDH1.setR(ECDH_Parameter_R, (short) 0, (short) ECDH_Parameter_R.length);
KeyPairECDH1 = new KeyPair(PublicKeyECDH1, PrivateKeyECDH1);
KeyPairECDH1.genKeyPair();
PrivateKeyECDH2 = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
KeyBuilder.LENGTH_EC_FP_192, false);
PrivateKeyECDH2 = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
KeyBuilder.LENGTH_EC_FP_256, false);
PrivateKeyECDH2.setFieldFP(ECDH_Parameter_P, (short) 0, (short) ECDH_Parameter_P.length);
PrivateKeyECDH2.setA(ECDH_Parameter_A, (short) 0, (short) ECDH_Parameter_A.length);
PrivateKeyECDH2.setB(ECDH_Parameter_B, (short) 0, (short) ECDH_Parameter_B.length);
PrivateKeyECDH2.setG(ECDH_Parameter_G, (short) 0, (short) ECDH_Parameter_G.length);
PrivateKeyECDH2.setK(ECDH_Parameter_K);
PrivateKeyECDH2.setR(ECDH_Parameter_R, (short) 0, (short) ECDH_Parameter_R.length);
PublicKeyECDH2 = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
KeyBuilder.LENGTH_EC_FP_192, false);
PublicKeyECDH2 = (ECPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
KeyBuilder.LENGTH_EC_FP_256, false);
PublicKeyECDH2.setFieldFP(ECDH_Parameter_P, (short) 0, (short) ECDH_Parameter_P.length);
PublicKeyECDH2.setA(ECDH_Parameter_A, (short) 0, (short) ECDH_Parameter_A.length);
PublicKeyECDH2.setB(ECDH_Parameter_B, (short) 0, (short) ECDH_Parameter_B.length);
PublicKeyECDH2.setG(ECDH_Parameter_G, (short) 0, (short) ECDH_Parameter_G.length);
PublicKeyECDH2.setK(ECDH_Parameter_K);
PublicKeyECDH2.setR(ECDH_Parameter_R, (short) 0, (short) ECDH_Parameter_R.length);
KeyPairECDH2 = new KeyPair(PublicKeyECDH2, PrivateKeyECDH2);
KeyPairECDH2.genKeyPair();
} catch (CryptoException ce) {
ISOException.throwIt(SW_INTERNAL_ERROR);
}
}
public short GenerateSharedSecretKey() {
byte[] ECDHSecretKey = new byte[65];
//byte[] pubKey = {(byte)0x04,(byte)0xED,(byte)0xB0,(byte)0x0A,(byte)0x5B,(byte)0xF5,(byte)0x8D,(byte)0xAB,(byte)0x6A,(byte)0x74,(byte)0xED,(byte)0xCB,(byte)0x59,(byte)0xCF,(byte)0x02,(byte)0xAA,(byte)0x29,(byte)0x75,(byte)0x0A,(byte)0x1B,(byte)0x4A,(byte)0x4E,(byte)0x60,(byte)0x54,(byte)0x3A,(byte)0x5D,(byte)0x61,(byte)0xBC,(byte)0x6B,(byte)0xFC,(byte)0xD4,(byte)0x2C,(byte)0x0A,(byte)0x9B,(byte)0x56,(byte)0xB0,(byte)0x00,(byte)0xDD,(byte)0xCA,(byte)0x86,(byte)0x50,(byte)0x90,(byte)0xDC,(byte)0xBE,(byte)0x7B,(byte)0x0A,(byte)0x51,(byte)0x3A,(byte)0xE9};
short len = getCardPublicKeyPointW(PublicKeyPointW);
KeyAgreementECDH.init(PrivateKeyECDH1);
try {
ECDHSecretKeyLength = KeyAgreementECDH.generateSecret(PublicKeyPointW, (short)0,
len, ECDHSecretKey, (short)0);
} catch (CryptoException e) {
ISOException.throwIt(e.getReason());
}
return ECDHSecretKeyLength;
}
public short getCardPublicKeyPointW(byte[] PublicKeyPointW){
return PublicKeyECDH2.getW(PublicKeyPointW, (short) 0);
}
/**
* Returns the local shared interface; following client applet AID validation.
*
* @return ShareableInterface
*/
public Shareable getShareableInterfaceObject(AID ClientAID, byte Parameter) {
return this;
}
}
Code: Select all
public class ECCShareKeyClient extends Applet {
public byte[] InstanceAID = {0x01,0x02,0x03,0x04,0x05,0x06};
public static void install(byte[] bArray, short bOffset, byte bLength) {
// GP-compliant JavaCard applet registration
new ECCShareKeyClient().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x01:{
ECCShareKeyShareableInterface ecc = GetShareableInterface();
ecc.GenerateECDHKeyPair();
}
break;
case (byte)0x02 :{
ECCShareKeyShareableInterface ecc = GetShareableInterface();
ecc.GenerateSharedSecretKey();
}
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
public ECCShareKeyShareableInterface GetShareableInterface() {
AID SharedAppletAID = JCSystem.lookupAID(InstanceAID, (short) 0,
(byte) InstanceAID.length);
if (SharedAppletAID == null)
ISOException.throwIt(ISO7816.SW_FILE_INVALID);
ECCShareKeyShareableInterface SharedApplet = (ECCShareKeyShareableInterface) JCSystem
.getAppletShareableInterfaceObject(SharedAppletAID, (byte) 0);
if (SharedApplet == null)
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
return SharedApplet;
}
}