Summary
Tested with Open Smart Card Shell tool , it is part of Open Smart Card Development Platform. I used my expired credit card, executed the script dump.js, and read out the basic credit card information.
Installing the Smart Card Shell
Installation is simple, just follow the guide.
You can also use [Eclipse plug-in] to use the Smart Card Shell.
Use the Smart Card Shell
It is easy to use, just click “SCSH3GUI.CMD” to start the Smart Card Shell Windows GUI.
Below is the command example:
Running setup script config.js ... Smart Card Shell Scripting Engine (scdp4j) 3.13.220 ---------------------------------------------------------------------------- (c) 2005-2016 CardContact Systems GmbH, Minden, Germany (www.cardcontact.de) Enter 'help' for a command overview or 'quit' to close the shell >r 0000 3B 69 00 00 80 65 A2 01 01 01 3D 72 D6 ;i...e....=r. TS : 3B Direct logic TO : 69 K = 9 byte [historical characters] TB1 : 00 pa = 4 % [programming voltage accurancy] I = 25 mA [maximum current] P = 0 V [programming voltage] TC1 : 00 N = 0 etu [extra guardtime] Pre-issuing data : A20101013D ¢...= Error: Compact TLV length field exceeds historical bytes - truncated Card capabilities : DF selection by full DF name DF selection by partial DF name DF selection by file identifier Short EF identifier supported Record number supported >help q | quit Quit shell r | reset Reset card in reader a | apdu(string) Send APDU to card print(string, ..) Print string(s) load(file) Load and execute file assert(expression, ..) Assert that expressions are all true defineClass(file) Load Java class defining native objects restart Restart shell (clears all variables) or any other valid ECMAScript expression. See doc/index.html for the complete documentation. If this is the first time you use the Smart Card Shell and you want to try it out, then insert a card into your reader and enter load("tools/explore.js") >apdu('00A4000400') Card error SW1/SW2=6b00 - Checking error: Wrong parameter P1-P2 >apdu('00A4040000') 6F 65 84 08 A0 00 00 00 03 00 00 00 A5 59 73 4A 06 07 2A 86 48 86 FC 6B 01 60 0C 06 0A 2A 86 48 86 FC 6B 02 02 01 01 63 09 06 07 2A 86 48 86 FC 6B 03 64 0B 06 09 2A 86 48 86 FC 6B 04 02 55 65 0B 06 09 2B 85 10 86 48 64 02 01 03 66 0C 06 0A 2B 06 01 04 01 2A 02 6E 01 02 9F 6E 06 19 81 22 02 01 00 9F 65 01 FF >
To run the js script, you just need use load command, example: load('emv/dump.js')
Test on dump.js
Used my expired Citibank credit card.
Used Omnikey 5321v2 reader.
dump.js shell test result
>load('emv/dump.js') AIDA0 00 00 00 03 10 10 0000 83 02 02 76 ...v <-----Read application data as indicated in the Application File Locator.------ ---------------------Collect input to data authentication.---------------------> Record No. 2 0000 70 4D 57 13 41 47 46 30 66 66 66 66 D1 70 82 01 pMW.AGF0.c(H.p.. 0010 00 00 03 66 10 00 0F 5F 20 1A 58 49 4F 4E 47 20 ...&..._ .XIONG 0020 48 55 49 4C 49 4E 20 20 20 20 20 20 20 20 20 20 HUILIN 0030 20 20 20 20 9F 1F 18 30 30 30 30 30 30 30 30 30 ...000000000 Record No. 1 0000 70 81 B3 90 81 B0 67 51 D5 FE 44 74 C7 A7 F9 1D p.....gQ..Dt.... //below raw date was deleted... ... //above raw date was deleted... ------------------------------------------------------------------------------> <----------------------------Display Data Elements-----------------------------> Application Identifier (AID) - card: A0000000031010 Application Label: 5649534120435245444954 - VISA CREDIT Track 2 Equivalent Data (Magnetic Strip): Primary Account Number: 4147463066666666 Expiration Date (YYMM): 1705 Service Code: 201 Discretionary Data: 0000066660000 //below data element was deleted... ... //above data element was deleted... ------------------------------------------------------------------------------> >
EMV TLV Decoder
You can trace the log, and use EMV TLV Decoder to analyze the data, example as below,
00B20314F2 7081EF8F01089224CCE4335A1A3CD7E4271A50B8D804D95ABA4E349811244D73336D196A6D969F25025B27D99F3201039F4681B025EBB698F660FB9E177F4A611E2FD4AB4C14A86A159E8838D10B6E47C99956D78C2E04C870F525227ABAA8D46BFE09CF46A372CD6FEBF8B59CA22FC646B6B38C1A061A5AF1E4D7556303EA5F7924C519D6D5EA5E10A25B6F9A4F4421081F4E9C7865F7ADEC183D39489C0B4A34E947C2D535426A7545EF4A2B9BF3A19DC1A07252F70A63E7A94A85C46FD55AFDB2348C402FA53905123A97A161F07D8E712576DCC15E92A10E93E504804E09629048AE9F4701039F49039F37049F4A01829000 70 EMV Proprietary Template 8F Certification Authority Public Key Index 08 92 Issuer Public Key Remainder CCE4335A1A3CD7E4271A50B8D804D95ABA4E349811244D73336D196A6D969F25025B27D9 9F32 Issuer Public Key Exponent 03 9F46 Integrated Circuit Card (ICC) Public Key Certificate 25EBB698F660FB9E177F4A611E2FD4AB4C14A86A159E8838D10B6E47C99956D78C2E04C870F525227ABAA8D46BFE09CF46A372CD6FEBF8B59CA22FC646B6B38C1A061A5AF1E4D7556303EA5F7924C519D6D5EA5E10A25B6F9A4F4421081F4E9C7865F7ADEC183D39489C0B4A34E947C2D535426A7545EF4A2B9BF3A19DC1A07252F70A63E7A94A85C46FD55AFDB2348C402FA53905123A97A161F07D8E712576DCC15E92A10E93E504804E09629048AE 9F47 Integrated Circuit Card (ICC) Public Key Exponent 03 9F49 Dynamic Data Authentication Data Object List (DDOL) 9F3704 9F4A Static Data Authentication Tag List 82
About the source code
It may not be easy to debug the source code, I use the print function to print out the intermediate data, as below read out application data example shows.
It read out Application Interchange Profile (AIP) and the Application File Locator (AFL). For detail, can refer to EMV_v4.3_Book_3_Application_Specification.
The APDU command example is as below,
80A800000483020276 6114 80C0000014 80127C00080202001001010010030400180102019000 The GET PROCESSING OPTIONS command initiates the transaction within the ICC. The ICC returns the Application Interchange Profile (AIP) and the Application File Locator (AFL).
The source code is as below,
/** * Read application data as indicated in the Application File Locator. * Collect input to data authentication. * */ EMV.prototype.readApplData = function() { print("<-----Read application data as indicated in the Application File Locator.------"); print("---------------------Collect input to data authentication.---------------------"); // Application File Locator must exist assert(typeof(this.cardDE[EMV.AFL]) != "undefined"); var afl = this.cardDE[EMV.AFL]; //print("4444444444 " + afl); //08 02 02 00 10 01 01 00 10 03 04 00 18 01 02 01 // Must be a multiple of 4 assert((afl.length & 0x03) == 0); // Collect input to data authentication var da = new ByteBuffer(); while(afl.length > 0) { var sfi = afl.byteAt(0) >> 3; // Short file identifier var srec = afl.byteAt(1); // Start record var erec = afl.byteAt(2); // End record var dar = afl.byteAt(3); // Number of records included in data authentication //print("4444444444 " + sfi + " " + srec + " " + erec+ " " +dar); for (; srec <= erec; srec++) { // Read all indicated records var data = this.readRecord(sfi, srec); print("Record No. " + srec); print(data); // Decode template var tl = new TLVList(data, TLV.EMV); //print("55555555 " + TLV.EMV + " 666 " + data); assert(tl.length == 1); var t = tl.index(0); assert(t.getTag() == EMV.TEMPLATE); // Add data authentication input if (dar > 0) { if (sfi <= 10) { // Only value da.append(t.getValue()); //print("5555555 " + t.getValue()); } else { // Full template da.append(data); //print("6666666 " + data); } dar--; } // Add card based data elements to internal list var tl = new TLVList(t.getValue(), TLV.EMV); this.addCardDEFromList(tl); } // Continue with next entry in AFL afl = afl.bytes(4); } this.daInput = da.toByteString(); print(this.daInput); print("------------------------------------------------------------------------------>\n"); }
Reference
EMV TLV Decoder https://www.emvlab.org/tlvutils/
Open Smart Card Shell
dump.js source code
https://github.com/CardContact/OpenSC
CardContact Github
Open Smart Card Development Platform
Installing the Smart Card Shell
The Smart Card Scripting Environment for Eclipse (SSE4E)
EMV_v4.3_Book_3_Application_Specification