简体   繁体   中英

Parsing MagTek EMV TLV

I'm working with a MagTek DynaPro in a project to read credit card data and enter it into an accounting system (not my first post on this project). I've successfully leverage Dukpt.NET to decrypt MSR data, so that's been good ( https://github.com/sgbj/Dukpt.NET ). So I started working on getting the EMV data, and I've used the following MagTek document for TLV structure reference:https://www.magtek.com/content/documentationfiles/d99875585.pdf (starting at page 89). However, I'm having trouble reading the data.

I tried using BerTlv.NET ( https://github.com/kspearrin/BerTlv.NET ) to handle parsing the data, but it always throws an exception when I pass the TLV byte array to it. Specifically, this is what I get:

System.OverflowException : Array dimensions exceeded supported range.

I've also tried running the data through some other utilities to parse it out, but they all seem to throw errors, too. So, I think I'm left with trying to parse it on my own, but I'm not sure about the most efficient way to get it done. In some instances I know how many bytes to read in to get the data length, but in other cases I don't know what to expect.

Also, when breaking some of the data, I get to the F9 tag, and between it and the DFDF54 tag the hex reads as 8201B3. Now, the 01B3 makes sense considering the leading two bytes for full message length are 01B7, but I don't understand the 82. I can't assume that's the tag for "EMV Application Interchange Profile" since that's listed under the F2 tag.

Also, there's some padding of zeros (I think up to eight bytes worth) and four bytes of something else at the end that are excluded from two-byte message length at the very beginning. I'm not certain if that data being passed into parsers is causing a problem or not.

Refer the spec screenshot 1, as per EMV specs you are supposed to read the tags like below.

Eg tag 9F26 [1001 1111] the subsequent byte is also tag data - [0010 0110]
But when it is 9A [1001 1010], tag data is complete, length follows.

在此处输入图片说明

The spec also says to check the bit 8 of second byte of tag to see whether a third byte of tag follows like below, but practically you will not require it.

在此处输入图片说明

In real life you know upfront the tags you will encounter, so you parse through the data byte by byte, if you get 9F you look for the next byte to get the full tag and then next one byte of length, and if it is 9A, the next byte is length.

Note that length is also in Hex, which mean, 09 means 9 bytes, where as 10 means 16 bytes. For 10 bytes it is 0A.

I now bless you to fly!!

While @adarsh-nanu's answer provides the exact BER-TLV specs I believe what @michael-mccauley was encountering was MagTek's invalid usage of TLV tags. I actually stumbled through this exact scenario for the IDTech VIVOpay where they also used invalid tags.

I rolled my own TLV parsing routines and I specifically called out the non-conforming tags to force set a length when not in BER-TLV conformance. See example code below:

int TlvTagLen(uchar *tag)
   {
   int len = 0;            // Tag length

   // Check for non-conforming IDTech tags 0xFFE0 : 0xFFFF
   if ((tag[0] == 0xFF) &&
       ((tag[1] >= 0xE0) && (tag[1] <= 0xFF)))
      {
      len = 2;
      }

   // Check if bits 0-4 in the first octet are all 1's
   else if ((tag[len++] & 0x1F) == 0x1F)
      {
      // Remaining octets use bit 7 to indicate the tag includes an
      // additional octet
      while ((tag[len++] & 0x80) == 0x80)
         {
         // Include the next byte in the tag
         }
      }

   return len;
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM