繁体   English   中英

APDU读取文件Java卡程序

[英]APDU read file java card program

我使用netbeans制作了Java卡经典小程序

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

成为默认的APDU

0x80 0xB0 0x00 0x03 0x60从偏移量3开始的当前文件中读取60个字节

当我尝试此命令时,它Input data length != Lc around line 12返回错误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;

读取功能是

 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 < 0 || 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,-诺迪尔

您没有正确使用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);
}

暂无
暂无

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

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