java card pin
This commit is contained in:
parent
a1d944097b
commit
b5f2359881
|
@ -0,0 +1,86 @@
|
|||
package hwb1;
|
||||
|
||||
import javacard.framework.*;
|
||||
//import javacardx.annotations.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public class Applet1 extends Applet {
|
||||
byte str[] = JCSystem.makeTransientByteArray((short)20, JCSystem.CLEAR_ON_RESET);
|
||||
OwnerPIN pin;
|
||||
|
||||
public static void install(byte[] bArray, short bOffset, byte bLength) {
|
||||
new Applet1(bArray, bOffset, bLength);
|
||||
}
|
||||
|
||||
protected Applet1(byte[] bArray, short bOffset, byte bLength) {
|
||||
byte iLen = bArray[bOffset];
|
||||
byte cLen = bArray[(short)(bOffset + iLen + (short)1)];
|
||||
byte aLen = bArray[(short)(bOffset + cLen + (short)1)];
|
||||
|
||||
pin = new OwnerPIN((byte)3, (byte)4);
|
||||
pin.update(bArray, (short)(bOffset + iLen + cLen + 3), aLen);
|
||||
|
||||
|
||||
str = new byte[21];
|
||||
register();
|
||||
}
|
||||
|
||||
private void sendName(APDU apdu) {
|
||||
short len = apdu.setOutgoing();
|
||||
byte name[] = {'o','n','d','r','a'};
|
||||
if (len > name.length) ISOException.throwIt((short)
|
||||
(ISO7816.SW_CORRECT_LENGTH_00 + (short)(name.length)));
|
||||
|
||||
apdu.setOutgoingLength((short)len);
|
||||
apdu.sendBytesLong(name, (short)0, (short)len);
|
||||
}
|
||||
|
||||
private void storeData(APDU apdu) {
|
||||
if (!pin.isValidated()) {
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
}
|
||||
|
||||
short bufLen = apdu.setIncomingAndReceive();
|
||||
if (bufLen >= str.length) {
|
||||
short err = ISO7816.SW_WRONG_LENGTH;
|
||||
err |= (short)(str.length - (short)1);
|
||||
ISOException.throwIt(err);
|
||||
}
|
||||
|
||||
byte [] buf = apdu.getBuffer();
|
||||
Util.arrayCopyNonAtomic(buf, ISO7816.OFFSET_CDATA, str, (short)0, bufLen);
|
||||
str[(short)(str.length - (short)1)] = (byte)bufLen;
|
||||
}
|
||||
|
||||
private void sendData(APDU apdu) {
|
||||
if (!pin.isValidated()) {
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
}
|
||||
|
||||
short len = apdu.setOutgoing();
|
||||
if (len > (short)str[(short)(str.length - (short)1)]) ISOException.throwIt((short)
|
||||
(ISO7816.SW_CORRECT_LENGTH_00 + (short)(str.length - (short)1)));
|
||||
apdu.setOutgoingLength((short)(str.length - (short)1));
|
||||
apdu.sendBytesLong(str, (short)0, (short)(str.length - (short)1));
|
||||
|
||||
}
|
||||
|
||||
public void process(APDU apdu) {
|
||||
byte [] buf = apdu.getBuffer();
|
||||
|
||||
if (buf[ISO7816.OFFSET_CLA] != 0x00) {
|
||||
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
byte ins = buf[ISO7816.OFFSET_INS];
|
||||
switch(ins) {
|
||||
case 0x00: sendName (apdu); return;
|
||||
case 0x02: storeData(apdu); return;
|
||||
case 0x04: sendData (apdu); return;
|
||||
}
|
||||
|
||||
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package hwb1;
|
||||
|
||||
import javacard.framework.*;
|
||||
//import javacardx.annotations.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public class Applet1 extends Applet {
|
||||
AESKey crypt_key;
|
||||
AESKey mac_key;
|
||||
byte crypt_key_bytes[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||||
byte mac_key_bytes[] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
|
||||
Cipher crypt;
|
||||
Signature mac;
|
||||
|
||||
public static void install(byte[] bArray, short bOffset, byte bLength) {
|
||||
new Applet1(bArray, bOffset, bLength);
|
||||
}
|
||||
|
||||
protected Applet1(byte[] bArray, short bOffset, byte bLength) {
|
||||
crypt_key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
|
||||
crypt_key.setKey(crypt_key_bytes, (short)0);
|
||||
crypt = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
|
||||
|
||||
mac_key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
|
||||
mac_key.setKey(mac_key_bytes, (short)0);
|
||||
mac = Signature.getInstance(Cipher.ALG_AES_MAC_128_NOPAD, false);
|
||||
register();
|
||||
}
|
||||
|
||||
private void encrypt(APDU apdu) {
|
||||
byte[] buf = apdu.getBuffer();
|
||||
short inLen = apdu.setIncomingAndReceive();
|
||||
|
||||
if (inLen > 64 || (ilen % 16) != 0) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
|
||||
byte[] outBuf = new byte[64];
|
||||
byte[] macBuf = new byte[16];
|
||||
|
||||
crypt.init(crypt_key, Cipher.MODE_ENCRYPT);
|
||||
crypt.doFinal(buf, ISO7816.OFFSET_CDATA, inLen, outBuf, (short) 0);
|
||||
|
||||
mac.init(mac_key, Signature.MODE_SIGN);
|
||||
mac.sign(outBuf, (short) 0, (short) inLen, macBuf, (short) 0);
|
||||
|
||||
Util.arrayCopyNonAtomic(outBuf, (short) 0, buf, (short) 0, inLen);
|
||||
Util.arrayCopyNonAtomic(macBuf, (short) 0, buf, inLen, (short) 16);
|
||||
|
||||
apdu.setOutgoingAndSend((short) 0, (short) (inLen + 16));
|
||||
}
|
||||
|
||||
private void decrypt(APDU apdu) {
|
||||
byte[] buf = apdu.getBuffer();
|
||||
short inLen = apdu.setIncomingAndReceive();
|
||||
|
||||
// 64 encrypted + 16 signature
|
||||
if (inLen != 80) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
|
||||
short cryptDataLen = (short) (inLen - (short) 16);
|
||||
byte[] cryptBuf = new byte[64];
|
||||
|
||||
mac.init(mac_key, Signature.MODE_VERIFY);
|
||||
boolean isValidMac = mac.verify(buf, (short) 0, cryptDataLen, buf, cryptDataLen, (short) 16);
|
||||
if (!isValidMac) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
}
|
||||
|
||||
crypt.init(crypt_key, Cipher.MODE_DECRYPT);
|
||||
crypt.doFinal(buf, (short) 0, cryptDataLen, cryptBuf, (short) 0);
|
||||
|
||||
Util.arrayCopyNonAtomic(cryptBuf, (short) 0, buf, (short) 0, cryptDataLen);
|
||||
apdu.setOutgoingAndSend((short) 0, cryptDataLen);
|
||||
}
|
||||
|
||||
public void process(APDU apdu) {
|
||||
byte [] buf = apdu.getBuffer();
|
||||
|
||||
if (buf[ISO7816.OFFSET_CLA] != 0x00) {
|
||||
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
byte ins = buf[ISO7816.OFFSET_INS];
|
||||
switch(ins) {
|
||||
case 0x42: encrypt(apdu); ISOException.throwIt(ISO7816.SW_NO_ERROR);
|
||||
case 0x44: decrypt(apdu); ISOException.throwIt(ISO7816.SW_NO_ERROR);
|
||||
}
|
||||
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/////////////////
|
||||
// TEST SCRIPT //
|
||||
/////////////////
|
||||
//
|
||||
// get constant name
|
||||
0x80 0x00 0x00 0x00 0x00 0x05;
|
||||
// -> 0x6f, 0x6e, 0x64, 0x72, 0x61
|
||||
//
|
||||
// get constant too large
|
||||
0x80 0x00 0x00 0x00 0x00 0xab;
|
||||
// -> 0x6x 0x05
|
||||
//
|
||||
// save
|
||||
0x80 0x02 0x00 0x00 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x00;
|
||||
// -> 0x00
|
||||
//
|
||||
// load
|
||||
0x80 0x04 0x00 0x00 0x00 0x05;
|
||||
// -> 0x01 0x02 0x03 0x04 0x05
|
||||
//
|
||||
// save too large
|
||||
0x80 0x02 0x00 0x00 0x1e
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x00;
|
||||
// -> 0x67 0x14
|
||||
//
|
||||
// load too large
|
||||
0x80 0x04 0x00 0x00 0x00 0x1e;
|
||||
// -> 0x6c 0x14
|
||||
//
|
||||
// unknown instruction
|
||||
0x80 0xab 0x00 0x00 0x00 0x00;
|
||||
// -> 0x6d 0x00
|
|
@ -0,0 +1,40 @@
|
|||
/////////////////////
|
||||
// AES TEST SCRIPT //
|
||||
/////////////////////
|
||||
//
|
||||
// get constant name
|
||||
0x80 0x00 0x00 0x00 0x00 0x05;
|
||||
// -> 0x6f, 0x6e, 0x64, 0x72, 0x61
|
||||
//
|
||||
// get constant too large
|
||||
0x80 0x00 0x00 0x00 0x00 0xab;
|
||||
// -> 0x6x 0x05
|
||||
//
|
||||
// save
|
||||
0x80 0x02 0x00 0x00 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x00;
|
||||
// -> 0x00
|
||||
//
|
||||
// load
|
||||
0x80 0x04 0x00 0x00 0x00 0x05;
|
||||
// -> 0x01 0x02 0x03 0x04 0x05
|
||||
//
|
||||
// save too large
|
||||
0x80 0x02 0x00 0x00 0x1e
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x01 0x02 0x03 0x04 0x05
|
||||
0x00;
|
||||
// -> 0x67 0x14
|
||||
//
|
||||
// load too large
|
||||
0x80 0x04 0x00 0x00 0x00 0x1e;
|
||||
// -> 0x6c 0x14
|
||||
//
|
||||
// unknown instruction
|
||||
0x80 0xab 0x00 0x00 0x00 0x00;
|
||||
// -> 0x6d 0x00
|
Loading…
Reference in New Issue