2016-11-14 73 views
2

是否可以保存發送到該applet中的Java Card applet的所有APDU命令?例如:終端發送00 B2 01 0C 00,我想將它保存在我的小程序中的某個位置,以便稍後能夠分析它。記錄Java Card applet中的所有APDU

+0

你的意思是存儲在Java卡內?或者在運行時/終端/ IFD /等調用Java卡? –

+2

我的意思是存儲在Java卡內供以後分析 – Clarke

回答

5

當然可以。需要生成某種持久性緩衝區。有很多技巧可以做到這一點。

最簡單的方法是生成一個列表,其中每個節點都包含一個新的陣列,在該陣列中複製該命令。只需首先確定命令大小,然後複製所有內容。不要忘記複製類型2和類型4命令的Le字節。

可能最好的方法是生成一個巨大的數組並將每個命令複製到它。持久性數組只是使用new byte[size]生成的字段。請注意,數組的最大大小爲32 Ki - 1您可能希望將命令的大小存儲在命令之前,或存儲在單獨的持久數組中。

由於卡持久存儲的數量通常非常少,您可能需要生成某種循環緩衝區,您可以在其中重新使用或覆蓋最舊的命令。請注意,通常沒有垃圾回收可能,如果存在,通常只在啓動時運行,可能需要很長時間。

您可以立即複製小程序的process方法中的標題。一旦收到字節,您應該只複製其餘的命令數據,例如對於Le字節使用setIncomingAndReceive並最後使用setOutgoing/setOutgoingAndSend

最後你還需要一些命令來讀出日誌。請注意,如果包含Le字節,則命令可以是4 + 1 + 255 + 1 = 262字節。命令響應僅保存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循環緩衝區是一個不錯的解決方案。但是,要小心它的大小 - 如果時間太短,很快就會損壞持久存儲器。另一件事是你應該實現某種開關來啓用/禁用日誌,你應該啓用它來進行調試 - 這種日誌記錄機制會顯着減慢整個applet的速度。 – vojta

+0

全部都是如此。當然,你有一個選擇:要麼使用大量的內存(可能不存在)*或*重用內存。但是你是對的,通常在寫入10K或更多之後,智能卡可能會在一天之內完成。至於減速:寫入持久性內存通常非常緩慢,儘管每種內存類型都不相同。 –