APDU读取文件java卡程序

我用netbeans制作了java卡经典applet

当我编程读取操作时,我检查APDU中的第一个字节是0x80然后第二个是0xB0然后从字节2和3获取我将从文件中读取的偏移量然后取字节数为从字节4读取

将APDU作为默认值

0x80 0xB0 0x00 0x03 0x60这从当前文件读取60个字节,以偏移号3开始

当我尝试这个命令时它返回错误Input data length != Lc around line 12

经过一些重试,我发现了问题

问题是编译器假设字节4是数据的长度,所以在我的命令中他等待60个字节

当我搜索时,我发现当INS=B0时,字节4并不意味着发送数据长度

我不知道为什么它这样做,当我尝试调试编译器时甚至没有进入过程函数。

我的脚本文件是

 0x00 0xA4 0x04 0x00 0X06 0X87 0XF1 0X3F 0X5E 0X22 0X47 0x7F; 0x80 0xA4 0x00 0x00 0x02 0x3F 0x00 0x7F; 0x80 0xA4 0x00 0x00 0x02 0x50 0x15 0x7F; 0x80 0xA4 0x00 0x00 0x02 0x53 0x00 0x7F; 0x80 0xA4 0x00 0x00 0x02 0x50 0x31 0x7F; 0x80 0xB0 0x00 0x00 0x33 0x7F ; powerdown; 

读取function是

  void read(APDU apdu) { if(current.isDF())//can not read DF file { ISOException.throwIt((short)27014); } EFile f = (EFile)current; byte[]data=apdu.getBuffer(); short offset = Util.getShort(data, (short)2); if(offset  f.length)//can not read { ISOException.throwIt((short)27270); } data=apdu.getBuffer(); short len = (short)(data[4]&0xFF); if(offset + len > f.length)//can not read { ISOException.throwIt((short)26368); } apdu.setOutgoing(); apdu.setOutgoingLength(len); apdu.sendBytesLong(f.data, (short)(f.offset + offset),len);//return the data } 

第一个选择程序,然后选择文件,然后尝试读取不起作用的数据

但如果我做0x80 0xB0 0x00 0x00 0x02 0x00 0x00它从偏移0读取2字节写入虽然最后的0x00 0x00甚至没有在标准中使用

我的问题为什么我必须将命令中的数据作为数据的长度需要为红色

我该如何解决这个错误?

首先,为什么使用0x80作为CLS字节? 实际上0x80是为Global Platform命令保留的。 如果您的卡是2G,您应该使用0xA0,如果您的卡是3G,最好使用0x0x(通道0通常为0x00)。 第二个 – 读取二进制APDU是OUT APDU,这意味着P3指定了预期的数据长度,即:

 0x00 0xB0 P1 P2 P3 

其中:P1编码:

 | b8 | B7 | b6 | b5 | b4 | b3 | b2 | b1 | Meaning ---------------------------------------------------------------------------------------------------------------------- | 0 | X | X | X | X | X | X | X | b7-b1 is the offset to the first byte | | | | | | | | | to read – P2 is the low part of the offset ---------------------------------------------------------------------------------------------------------------------- | 1 | 0 | 0 | X | X | X | X | X | SFI referencing used, b1-b5 are the SFI | | | | | | | | | and P2 is the offset to the first byte to read 

P2 – 偏移

P3 – 是预期的长度,您不应该在之后指定任何其他字节。 如果P3等于0,则将传输256字节的数据

有关所有细节,请查看标准ETSI TS 102 221(http://pda.etsi.org/pda/home.asp?wki_id=,m5nDbNrlEWZbXcW5h86B) – 您不需要帐户,只需输入电子邮件地址即可下载它。

希望它会有所帮助。

KR,-Nodir

您没有正确使用Java Card API。 下面我添加了一段我从头顶输入的代码。 如果没有运行,请尝试编码并进行一些编辑。

 void read() { final APDU apdu = APDU.getCurrentAPDU(); final byte[] buf = apdu.getBuffer(); if(current.isDF()) { ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED); } final EFile file = (EFile) current; final short fileOffset = Util.getShort(buf, ISO7816.OFFSET_P1); if (fileOffset < 0 || fileOffset >= file.length) { ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); } // Ne (encoded by Le) is the *maximum* size of the response data final short ne = apdu.setOutgoing(); // Re is the actual number of the bytes to be returned final short fileDataLeft = file.length - fileOffset; final short re = ne < fileDataLeft ? ne : fileDataLeft; apdu.setOutgoingLength(re); apdu.sendBytes(file.data, fileOffset, re); }