Смарт-карта: pyscard получает оставшиеся байты от apdu

В настоящее время я могу правильно использовать pyscard для общения со своей смарт-картой, однако, когда размер apdu превышает 255 байт, мне нужно получить оставшиеся байты для команды.

Какой метод возвращает мне оставшиеся байты в pyscard? Насколько я понимаю, sw2 должен быть числом оставшихся байтов.

def _cmd(self, cl, ins, p1, p2, data=''):
        command = '%02x%02x%02x%02x%02x%s' % (cl, ins, p1, p2, len(data),
                                              data.encode('hex'))

        data, sw1, sw2 = self.reader.transmit(hex2cmd(command))


        return data, sw1 << 8 | sw2

    def _cmd_ok(self, *args, **kwargs):
        data, status = self._cmd(*args, **kwargs)
        if status != 0x9000:
            raise Exception('APDU error: 0x%04x' % status)
        return ''.join(map(chr, data))

3 ответа

Вы, вероятно, ссылаетесь на код состояния 61xx, где xx обозначает количество байтов, которые еще доступны. К сожалению, это может считаться само собой разумеющимся, только если ваша карта общается с использованием T=0. Затем GET RESPONSE вернет следующий кусок данных. Некоторые утверждают, что то же самое, возможно, должно использовать и другие протоколы связи, но это серьезные проблемы, как только возникает необходимость в безопасном обмене сообщениями, особенно с использованием счетчиков последовательности.

Самым чистым способом, применимым к любой команде, было бы использование спецификации расширения длины в вашем APDU, если ваша карта поддерживает его, но это, а также максимальный размер буфера должны быть определены. Если присутствует LC, то указывается расширенная длина с использованием нулей байтов, старшего байта, младшего байта и затем LE с старшим байтом, младшим байтом. Если LC нет, указатель расширенной длины (нулевой байт) должен предшествовать двухбайтовой спецификации LE. Подробнее (как всегда) см. ISO 7816-4.

Я знаю, что это некропостинг. Тем не мение:

Мой подход другой: 61 xx означает, что вам нужно получить дополнительные xx байты данных. Вы можете отправить

response, sw1, sw2 = connection.transmit([0x00,0xC0,0x00,0x00,0xXX])

вернуть байты 0xXX без опроса за 90 00 кв.

Вот как это сделать:

Вам необходимо отправить специальный APDU для запроса оставшихся данных и поиска статуса 0x61xx cl, ins, p1, p2, = (0x00, 0xa5, 0x00, 0x00)

def _cmd_ok(self, *args, **kwargs):
        data, status = self._cmd(*args, **kwargs)
        #get high bits
        low = status & 0xFF;
        high = status >> 8;

        if status != 0x9000:
            if high != 0x61:
                raise Exception('APDU error: 0x%04x' % status)
            else:
                while status != 0x9000:
                    part, status = self._cmd(0x00, 0xa5, 0x00, 0x00)
                    data = data + part

        return ''.join(map(chr, data))
Другие вопросы по тегам