Read EMV data from Mastercard/VISA Debit/Credit Card [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am trying to build an application to read/encode data on Cards, information like PAN, expiry, customer name, PIN etc, So far I could figure out that I need to send APDU commands to read data from Card but there seems to be no clear documentation available as to what commands are used for what purpose and in what particular sequence, I couldn't find out specifications from Mastercard/VISA. Is there some documentation that can be referred to?
Thanks,
Null

Extending the other answer:
SELECT PSE:
T-->C - 00A404000E315041592E5359532E444446303100 # select PSE
T<--C - response with FCI
T-->C - 00B2010C00
T<--C - reponse with record from selected file, read records starting from 1 until receive 6A83 (optional step in your case)
SELECT application DF with AID received in step 1):
T-->C - 00A4040007A000000003101000 # as example, Visa AID
T<--C - response with application DF FCI
GET PROCESSING OPTIONS - initialize transaction:
T-->C - 80A8000002830000 # check if PDOL presents on card, if not, only 8300 should be added to DATA filed of APDU
T<--C - 771282023C00940C0802020010010300180102019000 # just example reswponse, it will differ on different cards
The response on GET PROCESSING OPTIONS above is TLV encoded:
77 12 - response templait, containing response data
82 02 3C00 - AUC
94 0C 080202001001030018010201 - AFL
9000 - SW (Status Word), response ofapplication, telling you, that no errors occured
Note, that response to GET PROCESSING OPTIONS may be returned as 80 template, in that case, you must parse it yourelf:
80 0E - response templait, containing response data
3C00 - AUC (always 2 bytes long)
080202001001030018010201 - AFL
9000 - SW (Status Word), response ofapplication, telling you, that no errors
You are interesting in AFL, which points you, where to read data from (files and record numbers):
94 0C
08020200
08 - SFI (Short File Identifier)
02 - first record in file
02 - last record in file
00 - no of records to be added to Static Data Authentication
10010300
10 - SFI
01 - first record in file
03 - last record in file (respectively, 3 records to be read - 01, 02, 03)
00 - no of records to be added to Static Data Authentication
18010201
18 - SFI
01 - first record in file
03 - last record of file
01 - count of records from first record to be used for Static Data Authentication (01 record must be used)
SFI is encoded as follows:
08 = 0000 1000 - first 5 bits are real SFI, it equals to 01, last 3 bits are always set to 0
READ APPLICATION DATA - for precize READ APPLICATION DATA command coding check 3rd EMV Book:
T-->C - 00B2020C00 # SFI = 01, record = 02
T<--C - response with record
T-->C - 00B2021400 # SFI = 02, record = 01
T<--C - response with record
T-->C - 00B2031400 # SFI = 02, record = 02
T<--C - response with record
etc until you process last AFL record...
PAN, expiry, effective date, track 2 equivalent data, etc... usually is located in records which are set to be used in Sighed Data Authentication in AFL.
The example above is for T=1 protocol. If card runs T=0 protocol, in response to each APDU which assumes R-APDU (Response APDU) to contain Data field, card will return byte count ready to be read and you should issue GET RESPONSE commands which is described in Book 1 of EMV specification.
Hope it helps.

You must check EMV ICC card specifications to understand, how to read data from ICC, specifications are freely available to download. Specification is splitted into 4 parts (4 books). You are interested in 1st and 3rd books to read application.
The sequence of APDUs to read application data is the following:
1) SELECT PSE (Payment System Environment file), it contains a list of Application DFs installed on smart card. DFs are named by AID (Application ID), which you will use to create a list of available applications (candidate list) for selection, if you want it, or just find AID with the most less Application Priority Indicator (check EMV Book 1 for more information). This is optional step, you can start from step 2) and try to select both Visa and MasterCard AIDs to check which of them is available on ICC.
2) SELECT application which you want to run using correct AID from list you have got in step 1). AIDs of Visa and MasterCard:
A0000000041010 - MasterCard
A0000000031010 - Visa
It will return FCI (File Control Information) of Application file and make Application SELECTED on ICC itself (Check EMV Book 1 for more information).
3) GET PROCESSING OPTIONS - initiate transaction on ICC. This APDU increments ATC (Application Transaction Counter) and returns AUC (Application Usage Control) and AFL (Application File Locator), which must be used to read data you need (Check EMV Book 3 for info).
4) READ APPLICATION DATA - using AFL returned in 3) you can read Application data. AFL is constructed from several parts: containing information about file (SFI - Short File Identifier), first record number, last record number and count of records used in Signed Data Authentication:
1st byte - SFI
2nd byte - First record ID
3rd byte - Last record ID
4th byte - Count of records in file to be used in Signing Data Authentication
It contains 4 byte long information on every file with records to be read during transaction. Just run over AFL and read records from every SFI from first to last records, that is all (consult book 3 for more information).
You will be unable to read PIN from card, PIN is personalized in records, which are not available to read from outside. ICC uses PIN only inside using VERIFY command, and ICC just returns PIN verification result and PIN try counter if PIN was wrong.
EMV Book 1,also, describes 2 used data transmission protocols, T=0 and T=1. To work with ICCs it is essential to understand a difference between these protocols.
Each step above starts from APDU name to make you easier find information into EMV Books 1 and 3.
To encode data to different card - it is completely different story. You should check EMV CPS (Common Personalization Specification) and GlobalPlatorm specifications. Personalization process is much more complex.

Related

Parsing Set Width Text File

I am looking for a bit of guidance on how to parse CDR data from flat text files received from a PBX for reporting. The files are set width rather than using a delimiting character.
I have found something called text Field Parser but wonder if there is a better, simpler way.
http://csharphelper.com/blog/2017/02/use-a-textfieldparser-to-read-fixed-width-data-c/
I’ve added some examples from the vendor below so you can see the exact format and what the fields mean.
Example

The following is an example of an External SMDR record:
01/14 09:24 00:00:59 T201 003 P001 100 1011T 1405
Where,
 01/14 is the date the caller contacted your contact center 
09:24 is the time the call originated
 00:00:59 is the amount of time the agent spoke with the caller before transferring the call
 T201 is the number of the trunk that the caller dialed in to
 003 is the time to answer for the agent (not the time spent in queue)
P001 is the reporting number of the ACD path queue the call was queued to
 100 is the reporting number of the agent group
1011 is the ID of the agent who first answered the call
T is the transferred call identifier
 1405 is the ID of the agent whom the call was transferred to
This means that an outside caller dialed in to the contact center on Trunk 201, on January 14th at 9:24 AM. The call was queued to the ACD Path Queue 1 (shown as P001), queued to Agent Group 100, and answered by Agent 1011 after 3 seconds waiting in queue. The agent who answered the call talked to the customer for 59 seconds before transferring the call to Agent 1405.
 
Internal SMDR records
An Internal SMDR record is generated by the PBX when
1. A call is completed (i.e. when all parties involved in the call have hung up) between two devices on the PBX (extensions or agents), with no outside parties (trunks) involved in the call 
2. The call is an internal answered call only
 3. Calls to ACD queues report based on the dialable number of the queue, not the reporting number as found in the External SMDR records.
4. All parties in the call have their Class of Services set to enable SMDR Internal recording
5. The PBX has the Internal SMDR option enabled.


Example

The following is an example of an Internal SMDR record:
01/14 07:20 00:00:10 6979 002 6515 I 7015
Where,
 1/14 is the date the call was made
 07:20 is the time the call originated
 00:00:10 is the length of the call
6979 is the extension that the call was made from
 002 is the time to answer for the agent (not the time spent in queue)
6515 is the dialable number of the ACD queue the call was made to
I is the internal call identifier 
7015 is the ID of the agent who answered the call
This means that on January 14th at 7:20 AM, internal Extension 6979 dialed the ACD Queue P001 with dialable number 6515. The call was answered by Agent 7015 after 2 seconds of wait time. The two parties talked for 10 seconds. There was no external caller involved in this call
I want to be able to parse the CDR/ SMDR data above and put into a database so it can be reported on. I can quite easily do this with CSV data but just need some guidance on the best way to do this with set width data.
For fixed width parsing you'll want to use String.Substring(). Reference to the MS Docs.
In your example you would do something along the lines of (Note: I could be off by one, but you should get the general picture)
var line = "01/14 09:24 00:00:59 T201 003 P001 100 1011T 1405";
//If we think about the string as an array then:
//we start at index 0 and continue until we get to index 4.
var date = line.Substring(0,4) //This will be 01/14 as a string.
//We start at index 5 and continue until we get to index 10.
var time = line.Substring(5,10) //This shooould be 09:24 as a string.
You would continue in this fashion until you have all the data you'd want from the line.

Multiple ble advertisements in a UWP app

I am trying to publish multiple ble advertisements in a UWP app in c#. I can add 2 manufactor data to one publisher and those will be transmitted. However if I want to publish more the data is not possible. Is this even possible?
Sample code so far:
var publisher = new BluetoothLEAdvertisementPublisher();
publisher.Advertisement.ManufacturerData.Add(CreateData("Test");
publisher.Advertisement.ManufacturerData.Add(CreateData("AnotherTest");
publisher.start();
BluetoothLEManufacturerData CreateData(string data)
{
var dataWriter = new DataWriter();
dataWriter.WriteInt32(data.Length);
dataWriter.WriteString(data);
return new BluetoothLEManufacturerData(0xFFFE, dataWriter.DetachBuffer());
}
Tried to add another manufactor data, but I get an exception
Tried multiple bluetooth adapters but windows don't seem to start the second adapter.
Also tried multiple Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher but that also does not do the trick
We can put multiple manufacturer data in one BluetoothLE Advertisement. However, please note that the max length of an advertisement payload is 31 bytes.
Ref ADVERTISING AND SCAN RESPONSE DATA FORMAT (BLUETOOTH SPECIFICATION Version 4.0 [Vol 3] Page 375 )
The format of Advertising data and Scan Response data is shown in Figure
11.1. The data consists of a significant part and a non-significant part. The
significant part contains a sequence of AD structures. Each AD structure shall
have a Length field of one octet, which contains the Length value, and a Data
field of Length octets. The first octet of the Data field contains the AD type field. The content of the remaining Length - 1 octet in the Data field depends on the value of the AD type field and is called the AD data. The non-significant part extends the Advertising and Scan Response data when necessary and shall
contain all-zero octets.
BluetoothLEManufacturerData is one of these AD structures which AD Type is 0xFF.
For your first manufacturer data CreateData("Test"), its length is 1 (Lenght) + 1 (Type) + 2 (Company Id) + 8 (Your specific data), which is 12 bytes. And for the second manufacturer data, its length is 19 (1+1+2+15) bytes. With these two manufacturer data, the advertisement payload has already been 31 bytes. That's why you get an exception, when you try to add another manufacturer data. Actually, if you add one character in your date, for example using CreateData("Test=") instead of CreateData("Test"), you will also get the Invalid advertisement payload detected error.
So please make sure that the buffer length can fit within an advertisement payload. You can put multiple manufacturer data as long as its length is less than 31 bytes.
var publisher = new BluetoothLEAdvertisementPublisher();
publisher.Advertisement.ManufacturerData.Add(CreateData("T"));
publisher.Advertisement.ManufacturerData.Add(CreateData("A"));
publisher.Advertisement.ManufacturerData.Add(CreateData("S"));
publisher.start();

Decode EMV TLV Data

I am working on a POS application that supports EMV cards. I am able to read card data from a Verifone MX card reader in TLV, but I am facing issues in decoding the TLV data to readable data.
I am able to Split the data into TLV Tags and its values. The resultant value is in Hex instead of Decoded text.
Example:
This is a sample TLV data (I got this sample TLV Data here
6F2F840E325041592E5359532E4444463031A51DBF0C1A61184F07A0000000031010500A564953412044454249548701019000
When i check this TLV in TLVUtil, I get data in certain Tags in readable format (like Tag 50 here).
The Closest I could get in my application is this:
Tag Value
50 56495341204445424954
4F A0000000031010
61 4F07A0000000031010500A56495341204445424954870101
6F 840E325041592E5359532E4444463031A51DBF0C1A61184F07A0000000031010500A56495341204445424954870101
84 325041592E5359532E4444463031
87 1
90
A5 BF0C1A61184F07A0000000031010500A56495341204445424954870101
BF0C 61184F07A0000000031010500A56495341204445424954870101
I would like to know if there is any way to identify certain tags that need to be converted from Hex to string or if there is any TLV Parser and decoder available in .Net that can replicate the TLVUtil tool.
Complete list of EMV tags and are available in EMVCo 4.3 specification book 3 -
you can download from here - https://www.emvco.com/download_agreement.aspx?id=654
How data is represented differs from field to field. Check 'Annex A - Data Elements Dictionary'
Details on encoding is mentioned in section 4.3
Read both the sections and your problem solved.
There are only a few tags that need to be converted to string. Generally tags that are put on POS screen personalized in hex equivalent of readable string.
5F20 : Cardholder Name
50 : Application Label.
5F2D : Language Preference
You must know which tags can be converted.
As it seems to me, programmatically you can identify something like,
Tag is of one byte ( 5A - Pan number ) or it contain 2 byte ( 5F20 - CARD HOLDER NAME), AND
length is of 1 byte or 2 byte AND
Tag is primitiv or constructed. More you can read Here
and if you know the list you can get something useful Here, It define the format of tag that you are looking for.
Here you can hard coded the format as it is well defined.
Hope it helps.
That data beginni g with 6F is a File Control Information (FCI) responded by an EMV card after SELECT command. There is an example in this video also decoded and explained.
https://youtu.be/iWg8EBhsfjY
Its easy check it out

read/write SLE4442 memory card with WinSCard API in c#

A bit of background information:
Inorder to read/write to SLE4442 memory cards, my app is currently using an Omnikey Cardman 3021 USB card reader, a Sumbsembly Smartcard API (external dll) which is capable of wrapping CT-API calls (directed to omnikey's dll) so that I can read/write the memory card in my c# app.
The only problem here is that Omnikey only provides a 32-bit dll of their CT-API. I asked if they are going to produce a 64-bit version, but they couldn't be bothered.
Current situation:
Inorder to make my application 64-bit capable, I must rewrite it using Windows WinSCard API. The problem here is that there are no specific examples on the web how to do it. Also getting hold of working APDU commands is nearly impossible, but I've managed to aquire two slightly different versions that sort of work.
I have googled this a hundred times over many months and with what I have managed to gobble together I can finally read the SLE4442 memory card. But for the life of me I can't get writing to work.
The code:
I'm not going to post the entire code into this first post (if need be I can do it later or provide a link to the source code).
But I'll outline the basic steps.
1) SCardEstablishContext
2) Get the reader name via SCardListReaders
3) SCardConnect
4) Read entire memory with SCardTransmit and APDU new byte[] { 0xFF, 0xB0, 0, 0, 0 };
5) Verify pin with SCardTransmit and APDU new byte[] { 0xFF, 0x20, 0, 0, 3, 0xFF, 0xFF, 0xFF }; (Note that this does return 0x90;0x00 as a response, which means the verification should have been succesful)
6) Try to write with ScardTransmit and APDU new byte[] { 0xFF, 0xD6, 0, 0, 50, 1 }; (try to write value 1 at memory position 50) - I have also tried using an APDU with the first parameter being 0x00 and/or the second byte being 0xD0. The response has never been 0x90;0x00 so I assume there is an error during writing, but I haven't been able to find any meaning to the error codes returned.
Possible causes:
Because I can read a memory card with the WinSCard API then it must be possible to also write to one (side note - the memory card(s) that I try to write to are in in working condition, I haven't locked them down by failing to verify the PIN 3 times).
1) Maybe the write APDU command is wrong. Could be that the instruction byte (second byte) is incorrect, or the memory location uses some sort of an extended coding scheme.
2) Maybe the verify command didn't actually verify. As in the command itself is fine, which is why 0x90 was returned, but I must call or setup something first.
3) Just a hunch, but I think that this is the real culprit. While googling I did find some vague references to having to call the SCardControl method with parameter IOCTL_SMARTCARD_SET_CARD_TYPE and setting the card type to SLE4442. But again no working examples anywhere and my trial-and-error testing resulted in failures. I got "One or more of the supplied parameters could not be properly interpreted." and some other error messages as well, can't remember what they all were. Assuming the code I copy-pasted from google code has the right descriptions for the error codes.
What I need:
What I need is someone to post or direct me to a site that has full+working code in c# for read/write SLE4442 using WinSCard API and it must work in both 32-bit and 64-bit enviroments.
The code doesn't have to be foolproof - eg. handling every possible error situation nicely. I should be able to do that myself. But if it is (including the APDU command result descriptions - eg. 0x90;0x00 is success, but 0x6B;0x4D is... etc...) then all the better.
APDU for writing to card, in your example, should be:
FF D6 00 50 01 01
Our Omnikey (3121) terminal writes data on SLE4442/SLE4442 cards perfectly, try this APDU:
FF D6 00 04 10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E AA
see also:
http://acs.com.hk/drivers/eng/API_ACR122U.pdf, chapter 5.4
FF,D2,00,01,03,01,02,03 (new pin = 1,2,3) does not work (also after verifying existing PIN:
6D,00,FF,20,00,00 03,FF,FF,FF) - It returns error code 6D00.
For us (yet) not a huge problem, as we code our cards now with the Xiring XiMax terminal (programmable terminal with it's own SDK, the terminal can store data in flash memory).
However, we need to find a solution soon. I am interested in your (future) findings.
Do you have the Omnikey SDK? We can send you working examples in C++ that can change PSC (pin) and data on SLE4442/5542 cards.
This week (so not tomorrow, as previously stated, we have many things going on and are constantly ) we will test the (so far) working code with the Omnikey 1021). Hope to help you out.
We always have 50+ Omnikey 3121 readers on stock and we can offer you these (1+) for a far batter price. Let me know if you are interested.
I am also interested what where you are located and what applications you are developing.

Map element position in data file to class property

I need to read/write files, following a format provided by a third party specification. The specification itself is pretty simple: it says the position and the size of the data that will be saved in the file.
For example:
Position Size Description
--------------------------------------------------
0001 10 Device serial number
0011 02 Hour
0013 02 Minute
0015 02 Second
0017 02 Day
0019 02 Month
0021 02 Year
The list is very long, it has about 400 elements. But lots of them can be combined. For example, hour, minute, second, day, month and year can be combined in a single DateTime object.
I've split the elements into about 4 categories, and created separated classes for holding the data. So, instead of a big structure representing the data, I have some smaller classes. I've also created different classes for reading and writing the data.
The problem is: how to map the positions in the file to the objects properties, so that I don't need to repeat the values in the reading/writing class? I could use some custom attributes and retrieve them via reflection. But since the code will be running on devices with small memory and processor, it would be nice to find another way.
My current read code looks like this:
public void Read() {
DataFile dataFile = new DataFile();
// the arguments are: position, size
dataFile.SerialNumber = ReadLong(1, 10);
//...
}
Any ideas on this one?
Custom attributes was going to be my suggestion, but I see you've already thought about that. Aside from that, my only other suggestion would be to store the mapping in, say, an XML file.

Categories

Resources