How to use pyscard to read NFC tag UID


Richard Grundy

Updated December 16, 2024 17:21

Overview

If you have NFC tags in your possession, you may want to read the data on the tag. One of the easiest ways to do this is using an SDK specifically created for connecting to and reading data from a tag.

In this tutorial, we'll go over the requirements necessary to connect a reader to your computer, send APDUs to your reader, and collect a tag's UID.

We'll be using an ACS WalletMate for our purposes, but the guide should work for other readers that are compliant with the CCID protocol.

Installing pcsc-lite

First we'll need the drivers that allow our computer to properly interface with the reader. For anyone using an ACS WalletMate, you'll need to download the drivers for your specific OS from the ACS website.

drivers-screenshot

Once you download them, be sure to install them! If you do not install them, then your script will not work. This will require you to restart your computer if you're using a Mac.

For anyone else, you'll likely need pcsc-lite which is a library for connecting to smart cards with your personal computer. It can be installed with brew:

brew install pcsc-lite

Installing pyscard and other dependencies

While pyscard is not the only NFC SDK, it is the one we like the best. For this tutorial you'll need the pyscard python package. You only need to run one of these:

python3 -m pip install pyscard pip3 install pyscard

Connecting to the reader

So now that we have the drivers, and the SDK installed. Let's plug our reader into the computer we want to run scripts on. Please note that you could very easily plug the reader into a Raspberry Pi. For our purposes, we're going to be using a Macbook Air.

Sending APDUs

The whole purpose of pyscard is to make sending APDUs easier. We have a useful crash course on APDUs here if you are unfamiliar with them. We're going to need to send an APDU to our WalletMate, so let's do it.

Reading NFC tag UID

The APDU for getting an NFC tags UID on an ACS WalletMate is the following:

CLAINSP1P2LE
FFCA000000

We can do that in python with pyscard like so:

Make sure you have your tag touching the reader when you run this script!

from smartcard.scard import ( SCardGetErrorMessage, SCARD_SCOPE_USER, SCARD_S_SUCCESS, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_PROTOCOL_T1, SCARD_CTL_CODE, SCardEstablishContext, SCardListReaders, SCardConnect, SCardControl ) hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER) assert hresult == SCARD_S_SUCCESS hresult, readers = SCardListReaders(hcontext, []) assert len(readers) > 0 reader = readers[0] hresult, hcard, dwActiveProtocol = SCardConnect(hcontext, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) apdu_cmd = [0xFF, 0xCA, 0x00, 0x00, 0x00] hresult, response = SCardControl(hcard, SCARD_CTL_CODE(3500), apdu_cmd) if hresult != SCARD_S_SUCCESS: print(SCardGetErrorMessage(hresult)) print('NFC tag UID is:', ''.join(map(lambda x: f'{x:02x}', response[:-2])).replace('0x', ''))

When you have a card placed against the reader scan surface and you run this, you should see:

drivers-screenshot

Conclusion

We went over some important tools for being able to collect a tag's UID in this guide, including pcsc-lite, the pyscard SDK and APDUs. You should now feel more confident in your ability to connect to a reader and get NFC tag UIDs!

If you have any feedback on this article, let us know! Email content@passninja.com

Was this article helpful?
Yes No