2016-11-14 3 views
2

Можно ли сохранить все команды APDU, отправленные в апплет Java-карты внутри этого апплета?Запишите все APDU внутри апплета Java Card

Например: терминал отправляет 00 B2 01 0C 00, я хочу сохранить его где-нибудь в моем апплете, чтобы иметь возможность проанализировать его позже.

+0

Вы хотите хранить внутри карты Java? Или в среде выполнения/терминале/IFD/и т. Д., Вызывающем карту Java? –

+2

Я хочу хранить внутри Java Card для последующего анализа – Clarke

ответ

5

Уверен, что это возможно. Требуется создать постоянный буфер. Для этого есть разные трюки.

Самый простой способ - создать список, в котором каждый узел содержит новый массив, в котором вы копируете команду. Просто сначала определите размер команды, затем скопируйте все. Не забудьте скопировать в байтах Le для команд типа 2 и типа 4.

Возможно, лучший способ - создать огромный массив и скопировать каждую команду на него. Стойкие массивы - это просто поля, созданные с использованием new byte[size]. Обратите внимание, что максимальный размер массива составляет 32 Ki - 1Вы можете захотеть сохранить размер команды перед командой или в отдельном постоянном массиве.

Поскольку количество постоянного хранения на карте обычно минимально, вы можете создать какой-то циклический буфер, где вы повторно используете или перезаписываете самые старые команды. Имейте в виду, что зачастую сбор мусора невозможен, и если он существует, он обычно работает только во время запуска, и это может занять много времени.

Вы можете сразу скопировать заголовок в метод апплета process. Вы должны копировать остальные данные команды только после получения байтов, например. после использования setIncomingAndReceive и, наконец, setOutgoing/setOutgoingAndSend для Le byte (s).

Наконец, вам нужна команда для чтения журнала. Обратите внимание, что команда может содержать 4 + 1 + 255 + 1 = 262 байт, если вы включили байт Le. Ответ команды содержит только 256 байтов + слово состояния. Поэтому вам может потребоваться прочитать его в нескольких частях, например. используя счетчик, чтобы указать конкретный APDU и смещение.

APDU с удлиненной длиной заслуживают отдельную главу, поэтому я оставлю их сейчас.


Я также оставить фактическую реализацию в качестве упражнения, если вы не возражаете, вы, вероятно, имеют интерфейс, такие как:

interface APDULogger { 
    short logNewCommand(byte[] commandHeader, short commandHeaderOffset); 
    void logNc(short nc); 
    void logCommandData(byte[] commandData, short commandDataOffset, short commandDataSize); 
    void logNe(short ne); 
} 

и

interface APDURetreiver { 
    void retrieveCommand(short history, byte[] commandHeader, short commandHeaderOffset); 
    short retrieveNc(); 
    short retrieveCommandData(byte[] commandData, short commandDataOffset, short maxCommandDataSize); 
    short retrieveNe(); 
} 

но заметьте, это просто не в моих силах. Возможно, вы захотите также сохранить некоторое состояние (одновременное обращение к методу logNe(short), вероятно, является ошибкой).

+0

Я не сказал, что это было легко. –

+3

+1 Циклический буфер - хорошее решение. Однако будьте осторожны с его размером - если период слишком короткий, вы очень скоро повредите свою постоянную память. Другое дело, что вы должны реализовать какой-то переключатель для включения/отключения журнала, и вы должны включить его только для отладки - такой механизм ведения журнала значительно замедлит работу всего апплета. – vojta

+0

Все верно. Конечно, у вас есть выбор: либо используйте много памяти (что может быть не там) *, либо * повторно использовать память. Но вы правы, обычно после того, как 10K пишет или еще, смарт-карта может назвать это днем.Что касается замедления: записи в постоянную память обычно очень медленные, хотя они различаются для каждого типа памяти. –

Смежные вопросы