是否可以保存发送到该applet内Java Card applet的所有APDU命令?
例如:终端发送00 B2 01 0C 00
,我想将它保存在我的applet中的某个位置,以便以后能够进行分析。
答案 0 :(得分:5)
当然可以。需要生成某种持久缓冲区。有各种各样的技巧可以做到这一点。
最简单的方法是生成一个列表,其中每个节点都包含一个新数组,您可以在其中复制命令。首先简单地确定命令大小,然后复制所有内容。不要忘记复制类型2和类型4命令的Le字节。
可能最好的方法是生成一个巨大的数组并将每个命令复制到它。持久数组只是使用new byte[size]
生成的字段。请注意,数组的最大大小为32 Ki - 1您可能希望在命令之前或在单独的持久数组中存储命令的大小。
由于卡上持久存储的数量通常非常小,您可能希望生成某种循环缓冲区,您可以重复使用或覆盖最旧的命令。请注意,通常没有可能的垃圾收集,如果它存在,通常只在启动期间运行,可能需要很长时间。
您可以立即在applet的process
方法中复制标题。一旦收到字节,您应该只复制其余的命令数据,例如使用setIncomingAndReceive
并最后使用setOutgoing
/ setOutgoingAndSend
作为Le字节后。
最后,您还需要一些命令来读取日志。请注意,如果包含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)
方法签名可能是错误的。)