< back index next >

Read EMV

File Structure

The files on a smart card are organized in a tree structure. The topmost file is the Master File (MF). The MF has one or more Application Definition Files (ADF). Inside of an ADF are Applicaton Elementary Files (AEF) that contain data.
You can quickly select an ADF with the Application Identifier (AID). Within an ADF you can select AEFs with the Short File Identifier (SFI).

APDU - Application Protocol Data Unit

After the reset, the communication between terminal and card works with APDUs.

Command APDU

The terminal sends a command APDU to the card. This command has a mandatory header and an optional body.

CLA INS P1 P2 Lc Data Le
Header Trailer

Field Description
CLA Class byte
0x00
INS Instruction byte
0xA4:Select Command
0xB2:Read Record Command
P1 Parameter 1 byte
The value and meaning depends on the instruction code (INS).
P2 Parameter 2 byte
The value and meaning depends on the instruction code (INS).
Lc Number of data bytes send to the card.
With the Smart Card Shell the value of Lc will be calculated automatically. You don't have to specify this parameter.
Data Data byte
Le Number of data bytes expected in the response. If Le is 0x00, at maximum 256 bytes are expected.

Response APDU

The card will execute the command and send a response APDU back to the terminal. The response APDU has an optional body consisting of data and a mandatory trailer with two status bytes "SW1" and "SW2". SW1 and SW2 combined are the status word (SW). If the status word has the value 0x9000 (SW1 = 0x90, SW2=0x00), the command was successfully executed by the card.

Data SW 1 SW 2
Body Trailer

Case 1 to 4

There are four different cases of APDU:

Case 1
Command: Header
Response: Trailer
Case 2
Command: Header + Le
Response: Data + Trailer
Case 3
Command: Header + Data
Response: Trailer
Case 4
Command: Header + Data + Le
Response: Data + Trailer

Read EMV Script

To read all data from the card, you can use the script contained in the following section:

try	
{
    var card = new Card(_scsh3.reader);
    card.reset(Card.RESET_COLD);

    var aid = new ByteString("A0000000041010", HEX); // MC
 // var aid = new ByteString("A0000000031010", HEX);  // VISA

 // var aid = new ByteString("1PAY.SYS.DDF01", ASCII);



    var fcp = card.sendApdu(0x00, 0xA4, 0x04, 0x00, aid, 0x00, [0x9000]);

    print("FCP returned in SELECT: ", new ASN1(fcp));

    for (var sfi = 1; sfi <= 31; sfi++) 
    {
        for (var rec = 1; rec <= 16; rec++) 
        {
            var tlv = card.sendApdu(0x00, 0xB2, rec, (sfi << 3) | 4, 0x00);
            if (card.SW == 0x9000) 
            {
                print("SFI " + sfi.toString(16) + " record #" + rec);
                try	
                {
                    var asn = new ASN1(tlv);
                    print(asn);
                }
                catch(e) 
                {
                    print(tlv.toString(HEX));
                }
            }
        }
    }
}

catch(e) 
{
	print("Exception reading from Credit Card Application: " + e.toString());
}

Line 06
This script works either with Mastercard or VISA because both cards are using different AIDs. You'll need to activate the AID that matches your card.

Line 13
To read the card's data we have to select the right ADF first. We'll do this with a SELECT command encoded as case 4 command APDU and transmitted using card.sendApdu():
The SELECT command supports the following options :

Parameter Description
0x00 Class byte
0xA4 Instruction byte
SELECT Command
0x04 Parameter 1 byte
Select a directory by name.
0x00 Parameter 2 byte
In general P2 is set to 0x00 when you write the complete AID Name.
aid Data bytes contain the directory name (AID)
0x00 Le byte
Set to 0x00 to retrieve the complete response of up to 256 bytes.
[0x9000] Array of acceptable SW1/SW2 return codes

The card.sendAPDU() method supports a further parameter, which is used to define a list of expected SW codes. [0x9000] defines a list with a single 0x9000 entry.

Line 17
Now we create a loop that starts with the first AEF (SFI=1) and ends with SFI 31.

Line 19
In a second loop the record number of every AEF will be iterated from 1 to 16.

Line 21
With the READ RECORD command issued using card.sendApdu() we can obtain the data.

Parameter Description
0x00 Class byte
0xB2 Instruction byte
READ RECORD Command
rec Parameter 1 byte. It contains the record number.
(sfi << 3) | 4 Parameter P2 byte. The first 5 bits contain the SFI and the last three bits are set to 1,0,0, which means that P1 is a record number.
To calculate the P2 parameter, the SFI will be shift three bits to the left and combinated with a '4'
e.g.
00000001
00001000 <<3
00000100 | 4
00001100 = 0x0C
0x00 Le byte. It is '00' so up to 256 bytes are expected.

Line 22
If the statusword has the value 0x9000 the command was successful and the tlv object will be printed.

< back index next >