简体   繁体   English

解析 MagTek EMV TLV

[英]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).我正在一个项目中使用 MagTek DynaPro 来读取信用卡数据并将其输入到会计系统中(不是我在这个项目上的第一篇文章)。 I've successfully leverage Dukpt.NET to decrypt MSR data, so that's been good ( https://github.com/sgbj/Dukpt.NET ).我已经成功地利用Dukpt.NET来解密 MSR 数据,所以这很好( 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).所以我开始着手获取 EMV 数据,并使用以下 MagTek 文档作为 TLV 结构参考:https ://www.magtek.com/content/documentationfiles/d99875585.pdf(从第 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.我尝试使用BerTlv.NET ( https://github.com/kspearrin/BerTlv.NET ) 来处理数据解析,但是当我将 TLV 字节数组传递给它时,它总是抛出异常。 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.此外,当破坏一些数据时,我会到达F9标签,在它和DFDF54标签之间,十六进制读取为 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.现在,考虑到完整消息长度的前两个字节是 01B7,01B3 是有意义的,但我不理解 82。我不能假设这是“EMV 应用程序交换配置文件”的标签,因为它列在F2标签下。

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.请参阅规范屏幕截图 1,根据 EMV 规范,您应该阅读如下标签。

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.规范还说要检查标签的第二个字节的第 8 位,以查看标签的第三个字节是否如下所示,但实际上您不需要它。

在此处输入图片说明

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.在现实生活中,您预先知道将遇到的标签,因此您逐字节解析数据,如果得到 9F,则查找下一个字节以获取完整标签,然后查找下一个字节的长度,如果是 9A ,下一个字节是长度。

Note that length is also in Hex, which mean, 09 means 9 bytes, where as 10 means 16 bytes.请注意,长度也是十六进制的,这意味着,09 表示 9 个字节,而 10 表示 16 个字节。 For 10 bytes it is 0A.对于 10 个字节,它是 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.虽然@adarsh-nanu 的回答提供了确切的 BER-TLV 规范,但我相信 @michael-mccauley 遇到的是 MagTek 对 TLV 标签的无效使用。 I actually stumbled through this exact scenario for the IDTech VIVOpay where they also used invalid tags.我实际上偶然发现了 IDTech VIVOpay 的这个确切场景,他们也使用了无效标签。

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.我推出了我自己的 TLV 解析例程,并且在不符合 BER-TLV 一致性时,我专门调用了不符合标准的标签以强制设置长度。 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;
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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