Introduction
Here we describe the steps for making your own, self-sovereign, self-custodial, contactless payment card to pay with Bitcoin over the Lightning Network.
The card uses open standards throughout and contains mitigation for replay attacks.
With this setup you can use your own server to authenticate a card tap, apply custom checks as required and make payment.
Contactless payment cards use Near Field Communication (NFC) with NFC Data Exchange Format (NDEF) messaging. Normally this would transmit a static message containing a link or other data but this would not be suitable for a payment card as the card could easily be copied onto another card. The interesting thing for us about the NTAG 424 DNA card (and others) by NXP is the Secure Unique NFC (SUN) message feature. SUN enables the card to be set up with secret keys to produce a message which changes each time it is read in a predictable way that can be verified on your server before it sends the payment.
Ok - let’s make one.
Resources
-
some cards
- either blank NXP DNA 424 NTAG cards/keyfobs/stickers
- or CoinCorner Bolt cards
-
a good NFC reader/writer
- Identiv uTrust 3700 F
-
software
-
reference documents
Steps
Check our setup
- start the NFC TagXplorer software
Connect
to the NFC card reader- place a card on the reader and click
Connect Tag
- verify the card description
Read the card
- select
NDEF Operations
andRead NDEF
- if you get this error, click
Format NDEF
and try again
- verify that the read completes without erroring
Start to set up the URI
- select
NTAG Operations
,Mirroring Features
andNTAG 424 DNA
- set
Protocol
tohttps://
- set
URI Data
to
lnurlw://card.yourdomain.com
- select
Add PICCDATA
andEnable SUN Message
- adjust the
URI Data
to
lnurlw://card.yourdomain.com?p=00000000000000000000000000000000&c=0000000000000000
- click after
p=
and note the p_position (38 in this case) - click after
c=
and note the c_position (73 in this case) - select
Write To Tag
- now go back to
NDEF Operations
andRead NDEF
- verify that the
NDEF Payload Info
is as expected
Finish setting up the URI template
- notice that the URI shows as
https://lnurlw://card ...
but we wantlnurlw://card ...
- go to
NTAG Operations
andNTAG 424 DNA
- select
Read/Write data
- select
File No
asNDEF File - 02
- click
Read
- the NDEF file is
0057D1015355046C6E75726C ...
. - look for the bytes
5504
(6 bytes from the start) 04
is the code forhttps://
URI prepending- change the
04
to00
to indicate no prepending for the URI
- click
Write
- now go back to
NDEF Operations
andRead NDEF
- verify that the
NDEF Payload(HEX) Info
is similar to that shown
- copy the hex data and convert to text, without the
0x00
prefix - verify you have your expected
URI data
value
Online hex to text tool
Set up the SUN authentication message
- go to
NTAG Operations
andNTAG 424 DNA
- select
Security Management
and clickAuthentiate First
- select
Get/Change File Settings
- set up the values in the order shown
- select
Change File Settings
- now go back to
NDEF Operations
andRead NDEF
- convert the hex data to text again
- verify that the
p
andc
values are non zero - select
Read NDEF
again - convert the hex data to text again
- verify that the
p
andc
values are in the right place - verify that the
p
andc
values change on each read
Change the application keys
- go to
NTAG Operations
andNTAG 424 DNA
- select
Security Management
- select
Authenticate
- leave the
Card Key No
set to00
- leave the
Key
value set to00000000000000000000000000000000
if not changed yet - click
Authenticate First
- select
Change Key
- select the
Card Key No
to change the key value for00
to04
- leave the
Old Key
value set to00000000000000000000000000000000
if not changed yet - enter a
New Key
value as required - enter a
New Key Version
value of00
or as required to keep track of your keys - click
Change Key
- repeat this to change all 5 application keys to your own values
Using the card
- the point-of-sale (POS) system will read the NDEF message from your card
- for example, NDEF message is
lnurlw://card.yourdomain.com?p=A2EF40F6D46F1BB36E6EBF0114D4A464&c=F509EEA788E37E32
- the POS will call your server here
https://card.yourdomain.com?p=A2EF40F6D46F1BB36E6EBF0114D4A464&c=F509EEA788E37E32
- your server should verify the payment request and issue an LNURLw response
LNURLw references
LUD-01: Base LNURL encoding and decoding
LUD-03: withdrawRequest base spec.
LUD-17: Protocol schemes and raw (non bech32-encoded) URLs.
Server side verification
- select
NDEF Operations
andRead NDEF
- convert the hex data to text
- for the
p
value and theSDM Meta Read Access Key
value, decrypt the UID and counter - for the
c
value and theSDM File Read Access Key
value, check with AES-CMAC
- the authenticated UID and counter values can be used on your server to verify the request
- your server should only accept an increasing counter value
- additional validation rules can be added at your server, for example
- an enable flag
- payment limits
- a list of allowed merchants
- a verification of your location from your phone
- your server can then make payment from your lightning node
Conclusion
We have shown that you can create your own, self-sovereign, self-custodial, contactless payment card for using Bitcoin over the Lightning Network.