An example of Flask application which can decrypt data contained in NDEF "mirrors" and validate their AES-CMAC cryptographic signature. Implemented according to AN12196 "NTAG 424 DNA and NTAG 424 DNA TagTamper features and hints".
Pull requests welcome.
Note: NTAG — is a trademark of NXP B.V.
Note: This GitHub project is not affiliated with NXP B.V. in any way. Product names are mentioned here in order to inform about compatibility.
Feel free to reach me at ml@icedev.pl if you have any questions concerning this topic.
If you are looking for a complete solution for tag configuration and management, check out the demo at kryptonfc.com. This app allows you to:
- Personalize blank NFC tags with just an NFC-enabled Android smartphone (no extra hardware required).
- Manage the list of your tags in a web panel.
- View the list of interactions with your tags (each scan is recorded in the table).
- Configure a simple landing page that is displayed to your users after the tag is scanned.
- Access the details about particular interaction through an API, directly from your website.
- Clone the repository
apt install -y git git clone https://github.com/icedevml/sdm-backend.git cd sdm-backend
- Setup the virtualenv
apt install -y python3 python3-pip python3-venv python3 -m venv venv source venv/bin/activate
- Install the required dependencies and copy example config:
pip3 install -r requirements.txt cp config.dist.py config.py
- Run Flask development server:
python3 app.py --host 0.0.0.0 --port 5000
- Visit localhost:5000 and check out the examples.
- Run
docker run -p 5000:80 icedevml/sdm-backend
- Visit localhost:5000 and check out the examples.
Use NXP's TagWriter application for Android. When writing an URL record, choose "Configure mirroring options". Refer to the tag's datasheet to understand particular options/flags.
Example:
http://myserver.example/tag?picc_data=EF963FF7828658A599F3041510671E88&cmac=94EED9EE65337086
Proposed SDM Settings for TagWriter:
- Enable SDM Mirroring (SDM Meta Read Access Right:
00
) - Enable UID Mirroring
- Enable Counter Mirroring (SDM Counter Retrieval Key:
00
) - Enable Read Counter Limit
- Enable Encrypted File Data Mirroring
Input URL:
http://myserver.example/tag?picc_data=00000000000000000000000000000000&cmac=0000000000000000
PICCDataOffset:
http://myserver.example/tag?picc_data=00000000000000000000000000000000&cmac=0000000000000000
^ PICCDataOffset
i.e.: in TagWriter, set the cursor between =
and 0
when setting offset.
SDMMACInputOffset/SDMMACOffset:
http://myserver.example/tag?picc_data=00000000000000000000000000000000&cmac=0000000000000000
^ SDMMACInputOffset/SDMMACOffset
SDMENCFileData mirror with PICCData Encrypted mirroring (must satisfy: CMACInputOffset != CMACOffset && SDMMACInputOffset == ENCDataOffset
)
Example:
http://myserver.example/tag?picc_data=FD91EC264309878BE6345CBE53BADF40&enc=CEE9A53E3E463EF1F459635736738962&cmac=ECC1E7F6C6C73BF6
Proposed SDM Settings for TagWriter:
- Enable SDM Mirroring (SDM Meta Read Access Right:
00
) - Enable UID Mirroring
- Enable Counter Mirroring (SDM Counter Retrieval Key:
00
) - Enable Read Counter Limit
- Enable Encrypted File Data Mirroring (Encryption data Length:
32
) - PICC Data Offset: set cursor between
picc_data=
and0
then clickSet PICC Data Offset
- Enc Data Offset: set cursor between
enc=
and0
then clickSet Enc File Mirroring Offset
- SDM MAC Input Offset: set cursor between
enc=
and0
then clickSet Offset
(upper button) - SDM MAC Offset: set cursor between
cmac=
and0
then clickSet Offset
(lower button)
In this case, TT Status Offset should be equal Enc Data Offset.
Example:
http://myserver.example/tagtt?picc_data=FDD387BF32A33A7C40CF259675B3A1E2&enc=EA050C282D8E9043E28F7A171464D697&cmac=758110182134ECE9
First two letters of File data (UTF-8)
will describe TagTamper Status (C
- loop closed, O
- loop open, I
- TagTamper not enabled yet).
- Edit
config.py
to adjust the decryption keys. - Setup nginx (with obligatory SSL encryption).
- Configure the application to run with uwsgi (example tutorial).
In general, SDMs generated with LRP cipher are not supported by this code. See icedevml/nfc-ev2-crypto for the implementation of LRP primitive. In test_lrp_sdm.py file, there is a short example of SDM message decryption with LRP primitive.