APDU читать файл программы Java-карты
Я сделал классический апплет Java-карты с использованием NetBeans
когда я программирую операцию чтения, я проверяю, что первый байт в APDU равен 0x80, а второй - 0xB0
затем возьмите смещение, которое я буду читать в файле из байтов 2 и 3, затем возьмите число байтов, которые будут считаны из байта 4
быть APDU по умолчанию
0x80 0xB0 0x00 0x03 0x60
это считывает 60 байтов из текущего файла, начиная с номера смещения 3
когда я пытаюсь эту команду, он возвращает ошибку Input data length != Lc around line 12
,
после некоторых попыток я нахожу проблему
проблема в том, что компилятор предполагает, что байт 4 является длиной данных, поэтому в моей команде он ждет 60 байт
при поиске я обнаружил, что байт 4 не означает длину отправляемых данных, когда INS=B0
я не знаю, почему это так, и когда я пытаюсь отладить, компилятор даже не входит в функцию процесса.
мой файл сценария
0x00 0xA4 0x04 0x00 0X06 0X87 0XF1 0X3F 0X5E 0X22 0X47 0x7F;
0x80 0xA4 0x00 0x00 0x02 0x3F 0x00 0x7F;
0x80 0xA4 0x00 0x00 0x02 0x50 0x15 0x7F;
0x80 0xA4 0x00 0x00 0x02 0x53 0x00 0x7F;
0x80 0xA4 0x00 0x00 0x02 0x50 0x31 0x7F;
0x80 0xB0 0x00 0x00 0x33 0x7F ;
powerdown;
функция чтения
void read(APDU apdu)
{
if(current.isDF())//can not read DF file
{
ISOException.throwIt((short)27014);
}
EFile f = (EFile)current;
byte[]data=apdu.getBuffer();
short offset = Util.getShort(data, (short)2);
if(offset < 0 || offset > f.length)//can not read
{
ISOException.throwIt((short)27270);
}
data=apdu.getBuffer();
short len = (short)(data[4]&0xFF);
if(offset + len > f.length)//can not read
{
ISOException.throwIt((short)26368);
}
apdu.setOutgoing();
apdu.setOutgoingLength(len);
apdu.sendBytesLong(f.data, (short)(f.offset + offset),len);//return the data
}
первым выберите программу, затем выберите файлы, а затем попробуйте прочитать данные, которые не работают
но если я сделаю 0x80 0xB0 0x00 0x00 0x02 0x00 0x00
он читает 2 байта записи со смещения 0, хотя последний 0x00 0x00
не используется даже в стандарте
моя проблема, почему я должен, но данные в команде должны быть как длина данных должна быть красной
как я могу исправить эту ошибку?
2 ответа
Прежде всего, почему вы используете 0x80 в качестве байта CLS? На самом деле 0x80 зарезервировано для команд глобальной платформы. Если ваша карта 2G, вы должны использовать 0xA0, а если ваша карта 3G, лучше использовать 0x0x (обычно 0x00 для канала 0). Второе - Read Binary APDU - OUT APDU, это означает, что P3 определяет ожидаемую длину данных, т.е.
0x00 0xB0 P1 P2 P3
где: P1 закодировано:
| b8 | B7 | b6 | b5 | b4 | b3 | b2 | b1 | Meaning
----------------------------------------------------------------------------------------------------------------------
| 0 | X | X | X | X | X | X | X | b7-b1 is the offset to the first byte
| | | | | | | | | to read – P2 is the low part of the offset
----------------------------------------------------------------------------------------------------------------------
| 1 | 0 | 0 | X | X | X | X | X | SFI referencing used, b1-b5 are the SFI
| | | | | | | | | and P2 is the offset to the first byte to read
P2 - это смещение
P3 - ожидаемая длина, и вы не должны указывать другие байты после. Если P3 равно 0, то 256 байтов данных будут переданы
Для получения более подробной информации, пожалуйста, проверьте стандарт ETSI TS 102 221 (http://pda.etsi.org/pda/home.asp?wki_id=,m5nDbNrlEWZbXcW5h86B) - вам не нужна учетная запись, просто введите адрес электронной почты, и вы сможете скачать его.
Надеюсь, это поможет.
КР, -Нодир
Вы не используете API Java Card правильно. Ниже я добавил кусок кода, который набрал на макушке головы. Пожалуйста, попробуйте код и отредактируйте его, если он не запускается.
void read() {
final APDU apdu = APDU.getCurrentAPDU();
final byte[] buf = apdu.getBuffer();
if(current.isDF()) {
ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
}
final EFile file = (EFile) current;
final short fileOffset = Util.getShort(buf, ISO7816.OFFSET_P1);
if (fileOffset < 0 || fileOffset >= file.length) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
// Ne (encoded by Le) is the *maximum* size of the response data
final short ne = apdu.setOutgoing();
// Re is the actual number of the bytes to be returned
final short fileDataLeft = file.length - fileOffset;
final short re = ne < fileDataLeft ? ne : fileDataLeft;
apdu.setOutgoingLength(re);
apdu.sendBytes(file.data, fileOffset, re);
}