byte
широко используется в разработке апплетов для Java Card.Поскольку карты имеют ограниченные ресурсы, каждый бит памяти драгоценен.Кстати, процессоры карты имеют ограничения в обработке целочисленных значений.Поддержка типа int
является необязательной, а java.lang.String
не поддерживается, поэтому все целочисленные операции и хранение данных осуществляются с помощью переменных и массивов byte
и short
.Поскольку целочисленные литералы имеют тип int
, они должны быть явно приведены к byte
или short
во всем коде.Связь с картой осуществляется через команды APDU, которые передаются апплету в виде массива byte
с, который должен быть разложен до byte
с для декодирования класса команд, команд и параметров.Глядя на следующий код, вы видите, насколько типы byte
и short
важны для разработки Java-карт:
package somepackage.SomeApplet;
import javacard.framework.*;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
public class SomeApplet extends Applet {
// Card status
private final static byte ST_UNINITIALIZED = (byte) 0x01;
private final static byte ST_INITIALIZED = (byte) 0x02;
// Instructions & Classes
private final static byte PROP_CLASS = (byte) 0x80;
private final static byte INS_INIT_UPDATE = (byte) 0x50;
private final static byte INS_EXT_AUTH = (byte) 0x82;
private final static byte INS_PUT_DATA = (byte) 0xDA;
private final static byte INS_GET_RESPONSE = (byte) 0xC0;
private final static byte INS_GET_DATA = (byte) 0xCA;
private final static short SW_CARD_NOT_INITIALIZED = (short) 0x9101;
private final static short SW_CARD_ALREADY_INITIALIZED = (short) 0x9102;
private final static byte OFFSET_SENT = 0x00;
private final static byte OFFSET_RECV = 0x01;
private static short[] offset;
private static byte[] fileBuffer;
private static short fileSize = 0;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SomeApplet( bArray, bOffset, bLength);
}
public RECSApplet(byte[] bArray, short bOffset, byte bLength) {
offset = JCSystem.makeTransientShortArray((short) 2, JCSystem.CLEAR_ON_RESET);
fileBuffer = new byte[FILE_SIZE];
byte aidLen = bArray[bOffset];
if (aidLen== (byte)0){
register();
} else {
register(bArray, (short)(bOffset+1), aidLen);
}
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short len = apdu.setIncomingAndReceive();
byte cla = buffer[ISO7816.OFFSET_CLA];
byte ins = buffer[ISO7816.OFFSET_INS];
short lc = (short) (buffer[ISO7816.OFFSET_LC] & 0x00ff);
while (len < lc) {
len += apdu.receiveBytes(len);
}
SecureChannel sc = GPSystem.getSecureChannel();
if ((short)(cla & (short)0x80) == ISO7816.CLA_ISO7816) {
switch (ins) {
case INS_PUT_DATA:
putData(buffer, ISO7816.OFFSET_CDATA, offset[OFFSET_RECV], len);
if ((cla & 0x10) != 0x00) {
offset[OFFSET_RECV] += len;
} else {
fileSize = (short) (offset[OFFSET_RECV] + len);
offset[OFFSET_RECV] = 0;
}
return;
case INS_GET_DATA:
case INS_GET_RESPONSE:
sendData(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
else if ((byte) (cla & PROP_CLASS) == PROP_CLASS) {
switch (ins) {
case INS_INIT_UPDATE:
case INS_EXT_AUTH:
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, sc.processSecurity(apdu));
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} else
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
// Some code omitted
}