ACR122U-A9 Reading NFC card 7 byte UID

1.2k views Asked by At

I have a Mifare Ultralight EV1 card that is supporting 7 byte UID according to documentation but when I read it using Buffer. from([0xFF, 0xCA, 0x00, 0x00, 0x00] I get only the four bytes from the APDT command.

Any points on how to get the full 7 bytes, when I use android or iOS reader they fetch the full 7 bytes UID, maybe the scanner does not support it?

This is the card scanned with an android phone: enter image description here

This is the code I am using: Also as Pastebin here: https://pastebin.com/uaaqX7e6

var pcsc = require('pcsclite');

var pcsc = pcsc();
pcsc.on('reader', function(reader) {

    console.log('New reader detected', reader.name);

    reader.on('error', function(err) {
        console.log('Error(', this.name, '):', err.message);
    });

    reader.on('status', function(status) {
        // console.log('Status(', this.name, '):', status);
        /* check what has changed */
        var changes = this.state ^ status.state;
        if (changes) {
            if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) {
                console.log("card removed");/* card removed */
                reader.disconnect(reader.SCARD_LEAVE_CARD, function(err) {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log('Disconnected');
                    }
                });
            } else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) {
                console.log("card inserted");/* card inserted */
                reader.connect({ share_mode : this.SCARD_SHARE_SHARED }, function(err, protocol) {
                    if (err) {
                        console.log(err);
                    } else {
                        // console.log('Protocol(', reader.name, '):', protocol);
                        // reader.transmit(Buffer.from([0x1B, 0xFF, 0xFF, 0xFF, 0xFF]), 40, protocol, function(err, data) {
                        //     if (err) {
                        //         console.log(err);
                        //     } else {
                        //         console.log('Data received', data);
                        //         //reader.close();
                        //         //pcsc.close();
                        //     }
                        // });

                        // const packet = new Buffer.from([
                        //     0xff, // Class
                        //     0xca, // INS
                        //     0x00, // P1: Get current card UID
                        //     0x00, // P2
                        //     0x00  // Le: Full Length of UID
                        //   ]);

                          const packet = new Buffer.from([
                            0xff, // Class
                            0xb0, // INS
                            0x00, // P1: Get current card UID
                            0x00, // P2
                            0x00  // Le: Full Length of UID
                          ]);
                          
                        //   reader.transmit(packet, 12,protocol, (err, response) => {
                          
                        //     if (err) {
                        //       console.log(err);
                        //       return;
                        //     }
                          
                        //     if (response.length < 2) {
                        //       console.log(`Invalid response length ${response.length}. Expected minimal length was 2 bytes.`);
                        //       return;
                        //     }
                          
                        //     // last 2 bytes are the status code
                        //     const statusCode = response.slice(-2).readUInt16BE(0);
                          
                        //     // an error occurred
                        //     if (statusCode !== 0x9000) {
                        //       console.log('Could not get card UID.');
                        //       return;
                        //     }
                          
                        //     // strip out the status code (the rest is UID)
                        //     const uid = response.slice(0, -2).toString('hex');
                        //     // const uidReverse = reverseBuffer(response.slice(0, -2)).toString('hex'); // reverseBuffer needs to be implemented
                          
                        //     console.log('card uid is', uid);
                          
                        //   });

                        reader.transmit(packet, 12, protocol, function(err, data) {
                            if (err) {
                                console.log(err);
                            } else {
                                console.log('Data received', data);
                                //reader.close();
                                //pcsc.close();
                            }
                        });
                    }
                });
            }
        }
    });

    reader.on('end', function() {
        console.log('Reader',  this.name, 'removed');
    });
});

pcsc.on('error', function(err) {
    console.log('PCSC error', err.message);
});

1

There are 1 answers

3
Andrew On

One way is to Read Binary Blocks 0 and 1

e.g. APDU = {FF B0 00 00 08}

Bytes 0,1,2,4,5,6,7 will be the 7byte UID.

Update

The command was adapted from the ACR122U manual

In Section 5.3

Read 4 bytes from the binary Page 04h (MIFARE Ultralight)

APDU = {FF B0 00 04 04h}

Read 16 bytes starting from the binary Page 04h (MIFARE Ultralight) (Pages 4, 5, 6 and 7 will be read)

APDU = {FF B0 00 04 10h}

Unfortunately this Card reader does not fully support NFC Forum Type 2 compliant cards (e.g. Mifare Ultralight C) or NFC Forum Type 2 compatible cards (e.g. Mifare Ultralight EV1) it only fully supports reading Mifare Classic cards, though there is a some commonality between these 3 types of cards hence you should be able do some operations

One difference is the size of the UID with the original Mifare Classic had a 4 byte UID, another is authentication.

For the Mifare Ultralight EV1 reading more than is block at once the doc you reference suggest this is capability is a bit dependant on the actual hardware.

I suggest you try sending:

FF B0 00 00 00 to read Block 00

and

FF B0 00 01 00 to read Block 01

to read each of the 2 block singularly

which your docs say is correct for a NFC Type 2 Card is always supported.

The UID of the Mifare Ultralight EV1 is bytes 0,1,2 of Block 00 and then bytes 0,1,2,3 of Block 01

Update 2

Unfortunately I'm not a expert on that particular card reader hardware, but the main part of the answer stands, the UID of the card is also stored in the memory of the at Blocks 0 and 1 as per the card's datasheet https://www.nxp.com/docs/en/data-sheet/MF0ULX1.pdf

And if you use NFC tools "Read Memory" option in the "Other" tab it will list the UID in blocks 0 and 1