Read Credit Card data via NFC with an Arduino/ESP8266
MasterCard paypass and VISA payWavepay technologies enable usage of credit cards with a simple swipe at the POS. It's a contactless technology using NFC to read (credit) card data. I always wondered, if it is possible to read credit card data via NFC on an Arduino. So I gave it try ...
I will not write a step by step how-to read a credit card with an Arduino, but I will point out the major steps. As prerequiste I asume you are familiar with Arduino, especially the Arduino IDE.
Hardware
Obvoiusly you will need a micro controller, an NFC reader and some test cards.
As micro controller I prefer the ESP8266 over the Arduino UNO because of it's much faster clock, much more RAM, much higher processing clock, much more functionality (i.e. WiFi on board) and much lower price. The pin out is somehow loony, therefore I'm using a NodeMCU which has breadboard friendly 2.54mm pins, a USB-interface and a logic for flashing without pressing any buttons. If you want stick to the Arduino UNO - no problem, it should fit even on the limited flash of the UNO.
As NFC reader I'm using the PN532 on the ELECHOUSE NFC Module V3.
Warning: Don't mess around with fakes in this particular case. Just buy the original one directly from Elechouse for around USD 14. The shipping i quite fast - mine came within two weeks. To point it out again: Some fakes on Aliexpress for USD 5 are working fine, but most of them are not reading credit cards. My ratio is 3 (non working) to 1 (working) card reader. So spear time - and money - and buy the original one.
For testing you will need cards. Lot of cards - the more the better - best from different brands. Even if VISA and MasterCard share the same standard - they set even the EMV standard - there are a lot of differences which you might find out when playing around with the cards. Even VISA and VPAY or Master and Maestro have differences in the used tags. And we do not only want to read credit cards - we also want to read debit cards. My bank issues debit cards with NFC since years and I'm lucky that they have also an Android App with a 100% EMV compatible SIM based card emulation and a wearable micro card. All these EMV cards - debit and credit - are readable with an Arduino / ESP8266.
Software
To program the Arduino UNO (or the ESP8266) I'm using the Arduino IDE. Not much to say about it - love it or leave it.
The Adafruit_PN532 NFC library for Arduino is a good starting point. Do yourself a favoir and play around with the shipped examples. Your hardware MUST work before you can go further. If the readMifare example doesn't show up the UID of your bank card don't even consider that the rest of this page will help you much. Most problems I had at the beginning was due to non working or counterfeight PN532 chips on fake modules. Once you have a working hardware - software shouldn't be a big issue.
Test Setup
Some words to my hardware setup:
My test hardware consist of the NodeMCU an ELECHOUSE NFC Module V3, a DC/DC converter, a breadboard with a RGB LED WS2811 and a 2way relay card. The DC/DC converter on the breadboard brings the 12 V from the AC/DC wall outlet to 5V for the NodeMCU. The relays are used to open / or close my door when a valid card is swiped. The RGB Led WS2811 is just perfect for the NodeMCU/ESP8266 because of the limited available GPIO's. You can control a lot of WS2811 on just one GPIO. So if you are running out of GPIOs but you have the need of displaying different states, head for the WS2811.
Using the Adafruit_PN532 NFC library
To send commands to the credit card with the Adafruit_PN532 library use the function inDataExchange.
Smartcards like credit or debit cards can be read by "Application Protocol Data Unit" - APDU.
In the next example I show a short example for how to send data to the card and receive data from the card. The APDU is an array with your command, and if successful, you will get back the answer (berBuffer), the length of the answer and a boolean success flag telling you if reading was "successful".
Arduino-C++:
bool success; uint8_t apdu[256]; uint8_t berBuffer[256]; uint8_t berLength=0; apdu[] ={0x00, 0xA4, 0x04, 0x00, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00}; success = nfc.inDataExchange(apdu, sizeof(apdu), berBuffer, &berLength);
If reading was successful
if (success)
you have the card data answer in the berBuffer and the length of your buffer in berLength. After these basics you are ready for:
Reading credit cards and debit cards
1 Application Selection
When talking with credit cards (and debit cards) the first step you do is to select the proper application. As nobody knows which card you are swiping - you could just try each AID after the other, as soon as the card responses with 90 00 you have a right one. Well known AIDs are
- A0000000031010 Visa International
- A0000000032020 Visa International
- A0000000041010 Mastercard International
- A0000000043060 Mastercard International United States Maestro (Debit)
AIDs can be found in internet. It is a common approach to try each known AID and offer each working AID to the cardholder for an "Application Selection" or to choose the application with the highest priority.
To select for example Maestro your ADPU will look following:
00 a4 04 00 07 a0 00 00 00 04 30 60 00
When the card answers with SW12=0x9000 the command was successfull
Payment System Environment (PSE)
The good thing about paypass/PayWave (NFC) reading versus reading from a contacted smart card reader is, that on most contactless enabled cards you will find a file "Payment System Environment (PSE)". That's a file containing the information which AIDs are available on the card.
The filename used on NFC cards is 2pay.sys.ddf01. So our first APDU command will send a read 2pay.sys.ddf01 command:
// 2 p a y . s y s . d d f 0 1 00 a4 04 00 0e 32 50 41 59 2e 53 59 53 2e 44 44 46 30 31 00
If you have success you get something back like:
6f 2c 84 0e 32 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 1a bf 0c 17 61 15 4f 07 a0 00 00 00 04 30 60 87 01 01 50 07 4d 41 45 53 54 52 4f 90 00
This is a nice BER-TLV. If not already done - you should google about BER-TLV. If you haven't found a BER-TLV parser yet, see the links on the end of the page. However, this is the information we got from PSE in a more readable form:
6F File Control Information (FCI) Template (44 Byte) 84 Dedicated file (DF) Name (14 Byte) 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 File Control Information (FCI) Proprietary Template (26 Byte) BF0C File Control Information (FCI) Issuer Discretionary Data (23 Byte) 61 Application Template (21 Byte) 4F Application Identifier (AID) - card (7 Byte) A0 00 00 00 04 30 60 87 Application Priority Indicator (1 Byte) 01 50 Application Label (7 Byte) 4D 41 45 53 54 52 4F
perfect: this card has an Application A0000000043060 - a MasterCard Debit (Maestro).
So next step is to start this AID:
00 a4 04 00 07 a0 00 00 00 04 30 60 00
hopefully we get something like:
6f 29 84 07 a0 00 00 00 04 30 60 a5 1e 50 07 4d 41 45 53 54 52 4f 5f 2d 04 64 65 65 6e 9f 38 03 9f 5c 08 bf 0c 05 9f 4d 02 0b 0a 90 00
Voila - we are in! This information looks very similar to the PSE, but beside the AID and the application label the first new information is the Language Preference of the cardholder. So if you plan to design a multi language GUI - here you have the cardholder preference. Up to 4 languages in the preferred order. In our example: de en - meaning German (de) and English (en). As mentioned - there can be up to 4 languages in the File Control Information (FCI).
Very important for further processing is the Processing Option Data Object List (PDOL). In the example 9F 5C 08
6F File Control Information (FCI) Template (41 Byte) 84 Dedicated file (DF) Name (7 Byte) A0 00 00 00 04 30 60 A5 File Control Information (FCI) Proprietary Template (30 Byte) 50 Application Label (7 Byte) 4D 41 45 53 54 52 4F 5F2D Language Preference (4 Byte) 64 65 65 6E 9F38 Processing Options Data Objekt List (PDOL) (3 Byte) 9F 5C 08 BF0C File Control Information (FCI) Issuer Discretionary Data (5 Byte) 9F4D Log Entry (2 Byte) 0B 0A
This concludes the application selection. Please keep in mind, that not each card has the PSE. If the PSE is missing you have to try'n'error each possible AID. Keep in mind, that there can be also more than one AID on the card. In this case you should ask the cardholder which AID should be started. For that reason each AID also has an Application Label. If you want to walk straight through - each application has a priority and you can choose the AID with the highest priority.
2 Initiate Application Process
With the information of the PDOL we can get the Application File Locator. My example card wants 8 bytes for the Tag 9F 5C. 9F 5C is "DS Requested Operator ID". Some cards might request other information from you, some cards don't provide information to PDOL.
So, we lookup each requested tag and try to provide the information to the card. If there are more tags requested, we concatenate our answers. If you can't find out which data to send, try a 00 value.
Our total datalength in the example is 8, we add the tag 83 which means we send 10 bytes (0x0a) to the card.
80 a8 00 00 0a 83 08 00 00 00 00 00 00 00 00 00 our APDU 00 00 00 00 00 00 00 00 the requested data 08 the length of all data 83 Tag for PDOL 0a Length of message incl. data length byte and Tag 83 80 a8 00 00 00 fixed
If the card doesn't request any PDOL in the FCI, just send an empty tag 83:
80 a8 00 00 02 83 00 00 our APDU 00 no data requested 83 Tag for PDOL 02 Length of message incl. data length byte and Tag 83 80 a8 00 00 00 fixed
What I've seen so far, VISA cards want additional information. Here are some examples of fields which must not be left zeroed:
Tag | Name | Length | example data |
---|---|---|---|
9F 66 | Terminal Transaction Qualifiers | 4 | 36 80 40 00 |
5F 2A | Transaction Currency Code | 2 | 09 78 |
Also GooglePay requests a lot of data.
Tag | Name | Length | example data |
---|---|---|---|
9F 1D | Terminal Risk Management Data | 8 | 40 40 80 00 00 00 00 00 |
9F 1A | Terminal Country Code | 2 | 00 40 |
9F 35 | Terminal type | 1 | 14 |
9F 01 | Acquirer Identifier | 1 | 01 |
9F 4E | Merchant Name and Location | 32 | 41 42 43 32 30 32 34 30 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
Our Maestro example answers:
77 16 82 02 19 80 94 10 08 01 03 03 10 01 02 00 10 04 04 00 20 01 01 01 90 00
and the most important information is the tag 94 Application File Locater (AFL). (Beside template 77 there are is also template 88 - but I don't have an example of that.)
77 Response Message Template Format 2 (22 Byte) 82 Application Interchange Profile (2 Byte) 19 80 94 Application File Locator (AFL) (16 Byte) 08 01 03 03 10 01 02 00 10 04 04 00 20 01 01 01
3 Read Application Data
Out of the information of the 94 Application File Locator we get information about the Application Files in groups of 4 bytes. In the example we got 4 groups:
SFI start end Number of records in data authentication 08 01 03 03 10 01 02 00 10 04 04 00 20 01 01 01
Now we can build the APDUs for each group. Meaning: one group can result in more APDUs. The first group of the example has start 1 and end 3 so a total of 3 files to read, the second group will generate 2 APDUs, the third one APDU and fourth group again each one APDU.
Each APDU will look like following:
//CLA = 0x00; //INS = 0xB2; //P1 = start - first record //P2 = Reference Control according Table //LE = Number of bytes to be read
P1 - the start - will be 1 for the first iteration of our first group. (Be careful with group 3, as it will start with 4!)
08 01 03 03
The five most significant bits of our actualGroup[0] contains the SFI. Therefore we shift to right to get the SFI
uint8_t SFI = actualGroup[0] >> 3;
So, if you had from our first group above
actualGroup[0] = 0x08 = 0b00001000;
you will get
SFI = 0b00000001;
Then the SFI has to be bit7..bit3 in P2. So you shift it to left.
Then we add 0b00000100 - meaning - you want to "Read all Records from P1 up to the last"
7 6 5 4 3 2 1 0 0 0 0 0 1 SFI 1 0 0 Read all Records from P1 up to the last 0 0 0 0 1 1 0 0 = 0x0c
in Arduino-C++:
uint8_t P2 = SFI <<3 | 0b00000100;
I know it looks somehow crazy, but that's the way we do it ;-)
Finally we have an APDU like
00 b2 01 0c 00
Here are the next two APDU of the first group:
00 b2 02 0c 00 00 b2 03 0c 00
Let's check the other groups for training:
second group: 10 01 02 00 ... from 1 to 2 means we should generate two APDUs. Do
the math on your own and you should get:
00 b2 01 14 00 00 b2 02 14 00
out from group 3: 10 04 04 00 ... as mentioned already: we start at 4(!)
00 b2 04 14 00
and one from group 4: 20 01 01 01
00 b2 01 24 00
You're still here? Great. Because now we get all the interesting data from the card when we send these APDUs to the card.
APDU 00 b2 01 0c 00 30 Bytes: 70 1a 57 13 67 00 85 80 49 76 67 91 08 0d 15 12 20 11 00 01 18 81 0f 5f 28 02 00 40 90 00 70 READ RECORD Response Message Template (26 Byte) 57 Track 2 Equivalent Data (19 Byte) 67 00 85 80 49 76 67 91 08 0D 15 12 20 11 00 01 18 81 0F 5F28 Issuer Country Code (2 Byte) 00 40 APDU 00 b2 02 0c 00 87 Bytes: 70 53 5f 24 03 15 12 31 5f 25 03 13 02 19 5a 0a 67 00 85 80 49 76 67 91 08 0f 5f 34 01 01 8c 27 9f 02 06 9f 03 06 9f 1a 02 95 05 5f 2a 02 9a 03 9c 01 9f 37 04 9f 35 01 9f 45 02 9f 4c 08 9f 34 03 9f 21 03 9f 7c 14 8d 0c 91 0a 8a 02 95 05 9f 37 04 9f 4c 08 90 00 70 READ RECORD Response Message Template (83 Byte) 5F24 Application Expiration Date (3 Byte) 15 12 31 5F25 Application Effective Date (3 Byte) 13 02 19 5A Application Primary Account Number (PAN) (10 Byte) 67 00 85 80 49 76 67 91 08 0F 5F34 Application Primary Account Number (PAN) Sequence Number (1 Byte) 01 8C Card Risk Management Data object List 1 (CDOL1) (39 Byte) 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 35 01 9F 45 02 9F 4C 08 9F 34 03 9F 21 03 9F 7C 14 8D Card Risk Management Data object List 2 (CDOL2) (12 Byte) 91 0A 8A 02 95 05 9F 37 04 9F 4C 08 APDU 00 b2 03 0c 00 33 Bytes: 70 1d 9f 4a 01 82 9f 49 03 9f 37 04 9f 44 01 02 9f 42 02 09 78 5f 30 02 02 01 9f 08 02 00 02 90 00 70 READ RECORD Response Message Template (29 Byte) 9F4A Static Data Authentication Tag List (1 Byte) 82 9F49 Dynamic Data Authentication Data Object List (DDOL) (3 Byte) 9F 37 04 9F44 Currency Exponent, Application (1 Byte) 02 9F42 Currency Code, Application (2 Byte) 09 78 5F30 Service Code (2 Byte) 02 01 9F08 Application Version Number (2 Byte) 00 02 APDU 00 b2 01 14 00 193 Bytes: 70 81 bc 8f 01 f1 92 04 9b 1a 84 43 90 81 b0 a0 c9 81 52 01 fd e4 b0 0f d9 32 6a c3 f8 44 1c 40 32 a1 cb 20 0d 66 e0 f2 4d e0 0b 4c 48 bf f6 e3 8f 15 64 05 6d 38 0a 47 52 4d 2d 35 1a f1 14 05 40 42 ff 1e 62 e5 89 3d ad dd e9 27 90 6c 67 26 5a 1b 28 b5 5a ed f0 d4 b3 95 60 d3 42 81 33 e7 bf 97 00 c5 73 01 64 43 0e 47 33 17 4d ff f6 b1 bc 82 cc a5 99 a8 91 df d8 33 0e c3 ab 23 e9 7b 4a 2e 5f dc a4 d9 38 4c 52 49 f5 6d a1 d1 2e ba 84 00 44 3e 8c 19 2f f5 00 75 06 21 1d 2b 16 7a d7 be 89 b1 1c fd 2b 67 f6 a0 ee cf 7c f7 2f 99 27 55 8a 6e de 5d 07 59 20 d2 cf 5f f6 ac fe 90 00 70 READ RECORD Response Message Template (188 Byte) 8F Certification Authority Public Key Index (PKI) (1 Byte) F1 92 Issuer Public Key Remainder (4 Byte) 9B 1A 84 43 90 Issuer Public Key Certificate (176 Byte) A0 C9 81 52 01 FD E4 B0 0F D9 32 6A C3 F8 44 1C 40 32 A1 CB 20 0D 66 E0 F2 4D E0 0B 4C 48 BF F6 E3 8F 15 64 05 6D 38 0A 47 52 4D 2D 35 1A F1 14 05 40 42 FF 1E 62 E5 89 3D AD DD E9 27 90 6C 67 26 5A 1B 28 B5 5A ED F0 D4 B3 95 60 D3 42 81 33 E7 BF 97 00 C5 73 01 64 43 0E 47 33 17 4D FF F6 B1 BC 82 CC A5 99 A8 91 DF D8 33 0E C3 AB 23 E9 7B 4A 2E 5F DC A4 D9 38 4C 52 49 F5 6D A1 D1 2E BA 84 00 44 3E 8C 19 2F F5 00 75 06 21 1D 2B 16 7A D7 BE 89 B1 1C FD 2B 67 F6 A0 EE CF 7C F7 2F 99 27 55 8A 6E DE 5D 07 59 20 D2 CF 5F F6 AC FE APDU 00 b2 02 14 00 16 Bytes: 70 0c 9f 47 03 01 00 01 9f 32 03 01 00 01 90 00 70 READ RECORD Response Message Template (12 Byte) 9F47 Integrated Circuit Card (ICC) Public Key Exponent (3 Byte) 01 00 01 9F32 Issuer Public Key Exponent (3 Byte) 01 00 01 APDU 00 b2 04 14 00 198 Bytes: 70 81 c1 9f 46 81 90 6e ad 30 f9 7c e6 57 11 80 15 f1 2a 67 c7 43 e7 de 01 4f 41 03 ff 73 67 59 cc 1c 2b 25 b4 ff 27 fc 26 4d c9 a2 fc 35 b9 bc 92 5a 5b 7c 07 81 4f 61 f8 cc 8e 32 3d 3d 8a 4b 25 8d 3c 5e c4 f3 7b a5 f0 f2 7b bb 46 60 73 4c fa de cb d4 96 6f 81 b9 45 57 4d 96 67 d5 46 96 99 55 72 a7 5d d3 57 f0 15 26 74 cf 87 bf a7 dd 05 48 a9 ee 98 45 3e da bf 3a d2 5e 6b fa ac 35 10 a7 ab 04 4b c7 6c d7 84 b0 25 ca 24 dc 31 35 42 e2 e7 f2 df cf a3 9f 48 2a 44 33 ac e8 83 29 bf 28 17 5c 44 58 68 5b 89 67 32 59 b8 d6 eb 0b a4 69 69 5b f5 92 e5 a8 72 6a b3 82 42 42 48 ef 7d 21 1a b1 90 00 70 READ RECORD Response Message Template (193 Byte) 9F46 Integrated Circuit Card (ICC) Public Key Certificate (144 Byte) 6E AD 30 F9 7C E6 57 11 80 15 F1 2A 67 C7 43 E7 DE 01 4F 41 03 FF 73 67 59 CC 1C 2B 25 B4 FF 27 FC 26 4D C9 A2 FC 35 B9 BC 92 5A 5B 7C 07 81 4F 61 F8 CC 8E 32 3D 3D 8A 4B 25 8D 3C 5E C4 F3 7B A5 F0 F2 7B BB 46 60 73 4C FA DE CB D4 96 6F 81 B9 45 57 4D 96 67 D5 46 96 99 55 72 A7 5D D3 57 F0 15 26 74 CF 87 BF A7 DD 05 48 A9 EE 98 45 3E DA BF 3A D2 5E 6B FA AC 35 10 A7 AB 04 4B C7 6C D7 84 B0 25 CA 24 DC 31 35 42 E2 E7 F2 DF CF A3 9F48 Integrated Circuit Card (ICC) Public Key Remainder (42 Byte) 44 33 AC E8 83 29 BF 28 17 5C 44 58 68 5B 89 67 32 59 B8 D6 EB 0B A4 69 69 5B F5 92 E5 A8 72 6A B3 82 42 42 48 EF 7D 21 1A B1 APDU 00 b2 01 24 00 47 Bytes: 70 2b 8e 0c 00 00 00 00 00 00 00 00 02 03 1f 03 9f 07 02 3d 00 9f 0d 05 b4 50 84 80 00 9f 0e 05 00 00 00 00 00 9f 0f 05 b4 70 84 80 00 90 00 70 READ RECORD Response Message Template (43 Byte) 8E Cardholder Verification Method (CVM) List (12 Byte) 00 00 00 00 00 00 00 00 02 03 1F 03 9F07 Application Usage Control (2 Byte) 3D 00 9F0D Issuer Action Code - Default (5 Byte) B4 50 84 80 00 9F0E Issuer Action Code - Denial (5 Byte) 00 00 00 00 00 9F0F Issuer Action Code - Online (5 Byte) B4 70 84 80 00
In some special cases the card could answer a request with something SW1=0x6C. When SW2 > 0 then you can send the command again with the provided length from SW2. for example:
APDU 00 b2 01 24 00 SW12 6C 2F APDU 00 b2 01 24 2F 47 Bytes: 70 2b 8e 0c 00 00 00 00 00 00 00 00 02 03 1f 03 9f 07 02 3d 00 9f 0d 05 b4 50 84 80 00 9f 0e 05 00 00 00 00 00 9f 0f 05 b4 70 84 80 00 90 00 7 SW12 90 00
At this point I will end this tutorial. You are now able to read most of the credit card data and debit card data. You get important information of the card, the PAN, or the track 2 equivalent data. It's not exactly the same like on the magentic stripe, but you will find most of data from the magnetic stripe also on the chip.
You could even generate an ARQC in the next step.
When dealing with card data you should follow the rules of PCI-DSS. For Example to mask the PAN on printouts for data security reasons. You see that I don't mask the PAN in my examples, however you should know that this is a not working PAN as I'm using an test card.