java card pin

This commit is contained in:
Hladu357 2024-10-20 17:28:08 +02:00
parent a1d944097b
commit b5f2359881
4 changed files with 255 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

40
lab01-03_java_card/test1.script Executable file
View File

@ -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

40
lab01-03_java_card/test2.script Executable file
View File

@ -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