简体   繁体   中英

APDU read file java card program

i made java card classic applet using netbeans

when i program the read operation i check for the first byte in the APDU to be 0x80 then the second to be 0xB0 then take the offset that i will read from in the file from the byte 2 and 3 then take the number of bytes to be read from byte 4

to be the APDU as the default one

0x80 0xB0 0x00 0x03 0x60 this read 60 bytes from the current file starting by offset number 3

when i try this command it returned error Input data length != Lc around line 12 .

after some retrying i find the problem

the problem is that the compiler assume that byte 4 is the length of data so in my command he wait for 60 bytes

when i search i find that byte 4 does not mean the sending data length when the INS=B0

i do not know why it made like this and when i try to debug the compiler did not enter the process function even.

my script file is

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;

the read function is

 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

    }

the first one to select the program and then select files and then try to read data that is not work

but if i do 0x80 0xB0 0x00 0x00 0x02 0x00 0x00 it read 2 bytes write from offset 0 although the final 0x00 0x00 is not used even in the standard

my problem why i must to but data in the command to be as length of the data needed to be red

how can i fix this error?

First of all why are you using 0x80 as CLS byte? Actually 0x80 is reserved for Global Platform commands. If your card is 2G you should use 0xA0 and if your card is 3G better to use 0x0x (usually 0x00 for channel 0). The second - Read Binary APDU is OUT APDU it means the P3 is specifying expected data length ie:

0x00 0xB0 P1 P2 P3

where: P1 coded:

|   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 - is offset

P3 - is expected length and you should not specify any other bytes after. If P3 is equal to 0 then 256 bytes of data will be transferred out

For all details please check standard ETSI TS 102 221 (http://pda.etsi.org/pda/home.asp?wki_id=,m5nDbNrlEWZbXcW5h86B) - you don't need account, just enter email address and you'll be able to download it.

Hope it will help.

KR, -Nodir

You are not using the Java Card API correctly. Below I added a piece of code that I typed out of the top of my head. Please try the code and edit it somewhat if it does not run.

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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