记录Java Card小程序内的所有APDU

Cla*_*rke 2 java apdu javacard

是否可以保存发送到该applet内的Java Card applet的所有APDU命令?

例如:终端发送00 B2 01 0C 00,我想将它保存在我的applet中的某个地方,以便以后能够进行分析.

Maa*_*wes 5

当然有可能.需要生成某种持久缓冲区.有各种各样的技巧可以做到这一点.

最简单的方法是生成一个列表,其中每个节点都包含一个新数组,您可以在其中复制命令.首先简单地确定命令大小,然后复制所有内容.不要忘记复制类型2和类型4命令的Le字节.

可能最好的方法是生成一个巨大的数组并将每个命令复制到它.持久化数组只是使用生成的字段new byte[size].请注意,数组的最大大小为32 Ki - 1您可能希望在命令之前或在单独的持久数组中存储命令的大小.

由于卡上永久存储的数量通常非常小,您可能希望生成某种循环缓冲区,您可以重复使用或覆盖最旧的命令.请注意,通常没有可能的垃圾收集,如果它存在,它通常只在启动期间运行,可能需要很长时间.

您可以立即process在applet 的方法中复制标头.一旦收到字节,你应该只复制其余的命令数据,例如在使用之后setIncomingAndReceive,最后是setOutgoing/ setOutgoingAndSend用于Le字节.

最后,您还需要一些命令来读取日志.请注意,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);
}
Run Code Online (Sandbox Code Playgroud)

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

但请注意,这只是我心中的首要问题.您可能也想保留一些状态(logNe(short)两次调用方法签名可能是一个错误).

  • +1循环缓冲区是一个不错的解决方案.但是,要小心它的大小 - 如果时间太短,你很快就会损坏你的持久记忆.另一件事是你应该为日志启用/禁用实现某种类型的开关,你应该只启用它来进行调试 - 这样的日志记录机制会显着减慢整个applet的速度. (3认同)