1
votes

I now work with value files on DESFire cards. I created a value file in my DESFire card with the following command:

byte[] cmdCreateValueFile = new byte[]{
        //cmd
        (byte)0xCC,
        //file no
        (byte)0x01, 
        //com.sett.
        (byte)0x00 ,
        //access rights
        (byte)0x44 , (byte)0x44,
        //lower limit
        (byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,
        //upper limit
        (byte)0x00 ,(byte)0x0F ,(byte)0x42 ,(byte)0x40 ,
        //initial value
        (byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,
        //limited credit enabled
        (byte)0x00
};

I then credit the value of file with this command:

//select my app first
...
doAuthenticate(); //authenticate with key #4 of my application

//credit in value file
tagResponse_cmdcredit = isodep.transceive(Utils.wrapMessage(
        (byte)0x0C, new byte[]{(byte) 0x01 , 
        //data
        (byte)0x00,(byte)0x00, (byte)0x03 , (byte)0xE8}));
Log.d("credittttttttttt", "111 "+Utils.bytesToHex(tagResponse_cmdcredit));

//do commit transaction
tagResponse_cmdCommitTransaction = isodep.transceive(Utils.wrapMessage(
        (byte)0xC7, null));
Log.d("committtttttttt", "111 "+Utils.bytesToHex(tagResponse_cmdCommitTransaction));

And my wrapMessage helper method looks like this:

public static byte[] wrapMessage (byte command, byte[] parameters) throws Exception {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    stream.write((byte) 0x90);
    stream.write(command);
    stream.write((byte) 0x00);
    stream.write((byte) 0x00);
    if (parameters != null) {
        stream.write((byte) parameters.length);
        stream.write(parameters);
    }
    stream.write((byte) 0x00);

    byte[] b = stream.toByteArray();
    return b;
}

But I recieve 91 9E error. What could be the problem?

1

1 Answers

0
votes

Edit: I found My mistake! I didnt heed MSB and LSB value initializing in the create value file command. It must be like this if lower limit be 0x00 0x00 0x00 0x00(zero) and upper value be 0x0F 0x42 0x40(1000 000):

tagResponse_cmdcreateValueFile = isodep.transceive(Utils.wrapMessage((byte)0xCC, new byte[]{(byte)0x01, 
                        //com.sett.
                        (byte)0x00 ,
                        //access rights
                        (byte)0x44 , (byte)0x44,
                        //lower limit
                        (byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,
                        //upper limit
                        (byte)0x40 ,(byte)0x42 ,(byte)0x0F ,(byte)0x00 ,
                        //initial value
                        (byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,
                        //limited credit enabled
                        (byte)0x00}));

I found my mistake! According to the DESFire documentation the value is always represented as LSB first.

When I want credit an amount of 1000 for example, I need to pass

(byte)0xE8, (byte)0x03, (byte)0x00, (byte)0x00

to the command instead of 0x00 0x00 0x03 0xE8 (where 03E8 is 1000 in decimal). When passing the value with MSB first, this would result in the decimal value -402456576 (signed 4-byte integer), which would be above the upper limit.