Reading NTAG216 User Data pages w/ ACR122U and Python

Hello people,
Following this guide Introduction to Smart Card Development on the Desktop [guide] I was able to read UID, FIRMVER by sending this instructions:

getuid: FF CA 00 00 00
firmver: FF 00 48 00 00

Now looking at the Reader and NTAG21x manuals…

I’m trying to figure out the instruction to Read a specific page, Authenticate, etc… but no success, things i’ve tried:

FF 30 04 00 00
FF 30 04 00 04
FF B0 00 04 00
FF 1B FF FF FF FF

… also tried the Direct Transmit instruction to FAST_READ 04 to 06 pages:
FF 00 00 00 04 04 06 3F 00

I found some sample codes that used similar instructions, but did not worked for my Reader:


            # let cmd = Buffer.from([
            #     0xFF, // Class
            #     0x00, // Direct Transmit (see ACR122U)
            #     0x00, // ...
            #     0x00, // ...
            #     0x03, // Length of Direct Transmit payload
            #     0xd4, // Data Exchange Command (see PN533 docs)
            #     0x42, // inserted
            #     0x60, // GET_VERSION
            # ]);

What’s the correct instruction to READ NTAG216 user memory pages using ACR122U? What am I doing wrong?

Thank you.

You are correct about needing to use the Direct Transmit function with the ACR122U, but you’ve truncated the actual command. Transparent mode transmission with the ACR122U requires both the direct transmit command parameters and the complete APDU. The FAST_READ command byte is 3A and you don’t have that in your attempted command above. Try this command, which is 5 bytes in total (hence the 5th byte is 05), includes the direct transmit command bytes D4 and 42, the FAST_READ command byte 3A, the start page byte 04, and the end page byte 06.

FF 00 00 00 05 D4 42 3A 04 06

The remaining CRC and DATA bytes listed in the NTAG216 documentation are not needed in this case.

Also the thing to know about APDUs is that ISO14443A chips like the NTAG216 use something called pseudo APDUs which is why you must use the direct transmit command in the first place. An APDU is a convention of ISO7816 over ISO14443A. Since the NTAG216 does not speak ISO7816, it is a pseudo APDU we’re dealing with which must be enveloped inside a normal ISO7816 command schema… that sandwiching or envelopment is the “direct transmit” command. The entire first part of the command FF 00 00 00 05 relates directly the APDU schema (CLA = FF, INS = 00, P1 = 00, P2 = 00, Lc = 05) … the body or “command data” of the APDU goes to the ACR122U and it sees D4 42 and says “ah, the rest of this command is meant to be sent directly to the contactless card as a raw command”.

The commands you sent previously like firmver FF 00 48 00 00 are actual APDUs that the reader handles for you based on real ISO7816 APDUs.

This all came about because smartcards used to be contact only… so there was no air interface or contactless protocols to worry about, and commands were sent directly to cards… but with the advent of contactless protocols like ISO14443A and ISO15693, there had to be some process of melding the two together in some way so a “contactless smartcard” could become a reality… and this is what we’re left with… so it’s no wonder it’s a bit confusing.

Make sense?

Further, when you are actually talking to a contactless smart card, like the VivoKey Flex One for example, then all commands you send will be real APDUs because the Flex One uses a chip that is a true contactless smart card and not a simple ISO14443A RFID chip. However because the Flex One is an ISO14443A contactless smart card, it must comply with ISO14443A rules, like send a UID out when it powers up, respond to the SELECT command so it knows the reader wants to talk to it… but beyond that, it will only respond to ISO7816 APDUs because that’s what it is.

Make sense?

1 Like