lnbits / boltcards

Bolt Cards (NXP NTAG424) - LNbits extension
MIT License
14 stars 9 forks source link

boltcard extension - static card id value is bad for user privacy #6

Open PeterRounce opened 1 year ago

PeterRounce commented 1 year ago

The current lnbits boltcard extension includes a per-card id value in the static lnurlw.

This is terrible for user privacy as every PoS (point-of-sale) that reads the card will get an unneccesary card identifier. While this does not directly identify the user, one link to the card user will identify them for all previous transactions on that PoS system.

Compare these two lnurlw schemes:

lnbits boltcard extension lnurlw://YOUR-DOMAIN.COM/boltcards/api/v1/scan/{YOUR_card_external_id}?p=00000000000000000000000000000000&c=0000000000000000

Bolt Card server lnurlw://card.yourdomain.com/ln?p=00000000000000000000000000000000&c=0000000000000000

Note It is also neccessary to ensure that GetVersion and GetCardUID do not return the card UID. I have prototyped this and verified that it is possible. This is due to be implemented in the Bolt Card app in the near future.

PeterRounce commented 1 year ago

The implementation difference is holding the AES decryption key at server level rather than card level, this enables the UID and counter value to be decrypted without knowing the UID beforehand.

The AES authentication key is at card level.

PeterRounce commented 1 year ago

The bolt card app plans to add uid_privacy as an optional flag on creating new bolt cards. https://github.com/boltcard/bolt-nfc-android-app/issues/25

This is designed to be backward compatible with LNbits bolt card extension so that it can be implemented in due course by the LNbits bolt card extension.

It addresses the note on NXP functions above (GetVersion and GetCardUID).

PeterRounce commented 1 year ago

There are some discussions here:

It seems that the most difficult part is the LNbits demo server.

The options are essentially:

  1. same decrypt key for every card - but it'll pretty much be public
  2. per card decrypt key - means trying each key on receiving a request
  3. per card static-id - privacy compromise

I think it's easy to overestimate the resources needed for option 2 above - it's only AES-128 . This can be implemented to give a high performance solution with low resource use and full privacy when combined with the uid_privacy update.

iWarpBTC commented 1 year ago

Maybe we could add some option for non static id bolt card in .env and bring back the method that will walk through all the card in that case trying to decrypt the link.

PeterRounce commented 1 year ago

An update to my earlier note about GetVersion and GetCardUID returning the card UID unless the NXP RandomID feature is enabled.

The NXP RandomID feature is now implemented in the latest Bolt Card app version as used by LNBits for the programming. Setting uid-privacy to y in the createbolt card response will signal the app to enable RandomID for the card.

https://github.com/boltcard/bolt-nfc-android-app/releases/tag/v0.1.4

RandomID cannot be disabled for a card.

With the any static/tracking ids removed from the lnurlw and this feature enabled, a POS can only see the provider domain and not the individual card identity. For reference, this is fully implemented in the Bolt Card server as an option when creating a card.