nfc-developer / sdm-backend

Backend server for Secure Dynamic Messaging (SDM). Supports decryption of PICCData, SDMENCFileData, and validation of SDMMAC. Compatible with NTAG 424 DNA (both variants). Written in Python 3 Flask. Pull requests welcome.
MIT License
75 stars 39 forks source link

Deciphering NTAG424 responses based on this repo's reference #46

Closed BarakChamo closed 10 months ago

BarakChamo commented 1 year ago

First, thank you for the excellent work on this repo. As others have mentioned, this is the only complete and working reference for how to get NDEF SDM working with the 424s.

I'm trying to build a simple Javascript-based client following the example from the code in this repo and using WebCrypto. However, when trying to decrypt responses coming from the ARX NFC Developer App on iOS I get errors.

For example, when using the following URL from the NTAG424: https://my424dna.com/?picc_data=FDE4AFA99B5C820A2C1BB0F1C792D0EB&enc=5F6F7965BAD8FA5FE7009D5A7D493BD5&cmac=C48B89C17A233B2C

I'm able to decrypt the tag data:

{"dataTag":"c7","uid":"04958CAA5C5E80","cnt":"010000","cntInt":1,"data":"78787878787878787878787878787878"}

And also able to use those values on your site: https://sdm.nfcdeveloper.com/tagtt?_____TRIAL_VERSION______NOT_FOR_PRODUCTION_____&picc_data=FDE4AFA99B5C820A2C1BB0F1C792D0EB&enc=94592FDE69FA06E8E3B6CA686A22842B&cmac=C48B89C17A233B2C

However, when trying the same code with values coming from the iOS app, I am able to use your site, but my code throws an error. This is the NDEF coming from the app: https://sdm.nfcdeveloper.com/tagtt?_____TRIAL_VERSION______NOT_FOR_PRODUCTION_____&picc_data=6107DD7607B179270EAFFCA2F0911940&enc=37C1E399E0948BEA54138F92DDD1E743&cmac=0406016621FC6AC6.

My question, since the NTAG documentation is quite convoluted: Both of these URLs seem to:

  1. not have the UID or counter mirrored as plaintext, only encrypted inside the picc_data.
  2. Both also have an enc for encrypted static data.
  3. It's the decryption of the static data, enc, that fails for me.

Since both URLs expose the same data, an encrypted PICC and ENC, I was expecting the same code to work for both.

Are there any particular details that need to be extracted from the PICC before or after decryption to change how the key for the ENC is constructed?

Thanks for your help!

BarakChamo commented 1 year ago

Some additional context for this issue: https://stackoverflow.com/questions/77432009/porting-node-js-crypto-code-to-subtlecrypto-webcrypto-fails-with-bad-decrypt/77432512#77432512

icedevml commented 10 months ago

The key derivation algorithm is defined here: libsdm/legacy_derive.py and the usage is here: app.py.

You have to run the key used in the NFC Developer App through these derivation functions in order to generate the actual keys that are physically on the tag.