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);
}
Другие вопросы по тегам