问题
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?
回答1:
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 i.e.:
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
回答2:
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);
}
来源:https://stackoverflow.com/questions/13378212/apdu-read-file-java-card-program