Search code examples
javasmartcardjavacardapdu

Strange data received from java smart card APDU?


I can send most data from the smart card without a problem. I noticed i always need to remove the first 6 bytes in the APDU to get the real data for some reason.

However, when sending one particular data, it's very hard to know where the data is in the APDU.

This is the code of the Java smartcard simulator:

data = new byte[] {(byte)0x6302}; 
apdu.setOutgoing();
apdu.setOutgoingLength((short) data.length);
apdu.sendBytesLong(data, (short) 0, (short) data.length);

The data expected to be sent/received is:

{0x2}

However, the data received in the middleware response APDU is:

responseApdu.getData():

{0x80, 0x32, 0x0, 0x0, 0x8, 0x0, 0x0, 0x1, 0x5c, 0x6, 0xf9, 0x63, 0x33, 0x1, 0x2, 0x90, 0x0}

I also tried logging the APDU that is sent by the java card simulator; it is the following data:

SendAPDU() data (apdu.getBuffer()):

{0x2, 0x32, 0x0, 0x0, 0x8, 0x0, 0x0, 0x1, 0x5c, 0x6, 0xf9, 0x63, 0x33, 0x0, ..... (all 0x0 after this point)}

Offset CDATA: 5

Can somebody help me understand why the data sent (or read before even sending) is so different from the actual data sent? Is it some kind of padding? How can I get the original data sent?


Solution

  • Change code to:

    data = new byte[] {(byte) 0x63, (byte) 0x02}; 
    apdu.setOutgoing();
    apdu.setOutgoingLength((short) data.length);
    apdu.sendBytesLong(data, (short) 0, (short) data.length);
    

    The data bytes { 0x63, 0x02 } will be sent out.

    And the data you mentioned in your question:

    1. The Response APDU data is:
    responseApdu.getData():
    {0x80, 0x32, 0x0, 0x0, 0x8, 0x0, 0x0, 0x1, 0x5c, 0x6, 0xf9, 0x63, 0x33, 0x1, 0x2, 0x90, 0x0}
    

    Means command data is: { 0x80, 0x32, 0x0, 0x0, 0x8, 0x0, 0x0, 0x1, 0x5c, 0x6, 0xf9, 0x63, 0x33, 0x1};, and response data is: { 0x2, 0x90, 0x0 };

    1. The apdu buffer is:
    SendAPDU() data (apdu.getBuffer()):
    {0x2, 0x32, 0x0, 0x0, 0x8, 0x0, 0x0, 0x1, 0x5c, 0x6, 0xf9, 0x63, 0x33, 0x0, ..... (all 0x0 after this point)}
    Offset CDATA: 5
    

    Means the data byte 0x02 will be sent (the sent length is 1 byte), the SW 0x9000 ({ 0x90, 0x00 }) will be sent after this byte. The Offset CDATA is not used when outgoing. And other data bytes in the APDU buffer is your APDU commands, the first byte is overwrite by the outgoing bytes (Here only 1 byte, 0x02).

    Note: process of APDU.sendBytesLong(data, offset, length):

    1). Copy data with offset and length to APDU buffer;

    2). Send data using APDU buffer;

    3). Send SW;