简体   繁体   English

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

[英]Log all APDUs inside a Java Card applet

Is it possible to save all APDU commands sent to a Java Card applet inside that applet? 是否可以将发送到Java Card小程序的所有APDU命令保存在该小程序中?

For instance: terminal sends 00 B2 01 0C 00 , I want to save it somewhere inside my applet in order to be able to analyse it later. 例如:终端发送00 B2 01 0C 00 ,我想将其保存在我的applet内的某个地方,以便以后进行分析。

Sure that's possible. 当然可以。 It is required to generate a persistent buffer of some kind. 需要生成某种持久缓冲区。 There are various tricks to do this. 有很多技巧可以做到这一点。

The easiest one is to generate a list, where each node holds an new array in which you copy the command. 最简单的方法是生成一个列表,其中每个节点都有一个新数组,您可以在其中复制命令。 Simply determine the command size first, then copy everything in. Don't forget to copy in the Le bytes for type 2 and type 4 commands. 只需简单地确定命令大小,然后复制所有内容即可。不要忘记为类型2和类型4命令复制Le字节。

Probably the best method is to generate a huge array and copy each and every command to it. 最好的方法可能是生成一个巨大的数组并将每个命令复制到该数组。 Persistent arrays are simply fields generated using new byte[size] . 持久数组只是使用new byte[size]生成的字段。 Note that the maximum size of the array is 32 Ki - 1You may want to store the size of the command before the command or in a separate persistent array. 请注意,数组的最大大小为32 Ki-1您可能希望将命令的大小存储在命令之前或单独的持久性数组中。

As the amount of on card persistent storage is usually pretty minimal you may want to generate some kind of cyclic buffer, where you reuse or overwrite the oldest commands. 由于卡上持久性存储的数量通常很少,因此您可能需要生成某种循环缓冲区,以便在其中重复使用或覆盖最早的命令。 Mind that there is often no garbage collection possible and if it exists it usually only runs during startup and it may take a long time. 请注意,通常不可能进行垃圾回收,如果存在,则通常仅在启动期间运行,可能会花费很长时间。

You can immediately copy the header in the process method of the applet. 您可以立即在applet的process方法中复制标题。 You should only copy the rest of the command data once you receive the bytes, eg after using setIncomingAndReceive and finally setOutgoing / setOutgoingAndSend for the Le byte(s). 收到字节后,您仅应复制其余命令数据,例如,在使用setIncomingAndReceive并最终为Le字节使用setOutgoing / setOutgoingAndSend

Finally you need some command to read out the log as well. 最后,您还需要一些命令来读出日志。 Note that a command can be 4 + 1 + 255 + 1 = 262 bytes if you include the Le byte. 请注意,如果包含Le字节,则命令可以是4 + 1 + 255 + 1 = 262个字节。 A command response only holds 256 bytes + the status word. 命令响应仅包含256个字节+状态字。 So you may need to read it out in multiple parts, eg using a counter to indicate the specific APDU and offset. 因此,您可能需要分多个部分读取它,例如使用计数器来指示特定的APDU和偏移量。

Extended length APDU's deserve a chapter all in themselves, so I'll leave them out for now. 扩展长度的APDU本身值得一章,因此我暂时将其省略。


I'll also leave the actual implementation as an exercise if you don't mind, you'd probably have an interface such as: 如果您不介意的话,我也会把实际的实现留作练习,您可能会有一个接口,例如:

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

and

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

but mind you, this is just out of the top of my mind. 但是请注意,这只是我的主意。 You may want to keep some state too (calling the logNe(short) method signature twice is probably an error). 您可能也想保持某种状态(两次调用logNe(short)方法签名可能是一个错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM