2016-11-14 90 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或更多之后,智能卡可能会在一天之内完成。至于减速:写入持久性内存通常非常缓慢,尽管每种内存类型都不相同。 –