【问题标题】:Parsing MagTek EMV TLV解析 MagTek EMV TLV
【发布时间】:2017-02-24 23:41:08
【问题描述】:

我在一个项目中使用 MagTek DynaPro 读取信用卡数据并将其输入到会计系统中(不是我在这个项目上的第一篇文章)。我已经成功地利用 Dukpt.NET 来解密 MSR 数据,这很好 (https://github.com/sgbj/Dukpt.NET)。因此,我开始着手获取 EMV 数据,并使用以下 MagTek 文档作为 TLV 结构参考:https://www.magtek.com/content/documentationfiles/d99875585.pdf(从第 89 页开始)。但是,我无法读取数据。

我尝试使用 BerTlv.NET (https://github.com/kspearrin/BerTlv.NET) 来处理数据解析,但是当我将 TLV 字节数组传递给它时,它总是抛出异常。具体来说,这是我得到的:

System.OverflowException : Array dimensions exceeded supported range.

我还尝试通过其他一些实用程序运行数据来解析它,但它们似乎也都会抛出错误。所以,我想我只能自己尝试解析它,但我不确定完成它的最有效方法。在某些情况下,我知道要读取多少字节才能获得数据长度,但在其他情况下,我不知道会发生什么。

此外,当破坏一些数据时,我会到达 F9 标记,在它和 DFDF54 标记之间,十六进制读取为 8201B3。现在,考虑到完整消息长度的前两个字节是 01B7,01B3 是有意义的,但我不理解 82。我不能假设这是“EMV 应用程序交换配置文件”的标签,因为它在 下列出F2 标签。

此外,还有一些零填充(我认为最多可达 8 个字节)和末尾的 4 个字节的其他内容,一开始就被排除在两字节消息长度之外。我不确定传递给解析器的数据是否会导致问题。

【问题讨论】:

    标签: c# emv tlv


    【解决方案1】:

    请参阅规范截图 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.
    

    规范还说要检查标记的第二个字节的第 8 位,以查看标记的第三个字节是否如下所示,但实际上您不需要它。

    在现实生活中,你预先知道你会遇到的标签,所以你逐字节解析数据,如果你得到 9F,你会寻找下一个字节来获得完整的标签,然后是下一个字节的长度,如果是9A,下一个字节是长度。

    请注意,长度也是十六进制的,这意味着,09 表示 9 个字节,而 10 表示 16 个字节。对于 10 个字节,它是 0A。

    我现在祝福你飞翔!!

    【讨论】:

    • 好的,所以我只是逐个检查并挑选 TLV 数据。事实证明,响应不符合 BER-TLV 标准,甚至不符合 MagTek 自己的文档中列出的格式。经过极大的耐心,我能够找到所有的部分,并且有些标签似乎没有用任何 EMV 标准定义。现在我只需要弄清楚如何区分芯片和条带读取,等等。谢谢。
    • Michael 你是如何拆分数据的?我一直在尝试解密 DFDF59,但使用 DUKTP 无法正确输出
    • DUPKT 与解析无关。 DUPKT 用于使用从 BDK 派生的一次性密钥加密数据,您将在另一端派生相同的密钥,并使用它解密数据。一旦你有了明确的数据,你就可以把上面提到的解析规则。只是为了确保您的 DUPKT 实现是正确的,我建议您测试各种各样的数据,看看您是否能够在另一端解密而没有任何问题。在生产环境中调试它会变得更加困难。
    • DUKPT 与 Magtek MSR 合作,目前正在尝试使用 DFDF56 (KSN) 解密标签 DFDF59(加密数据),Track 2 等效数据也没有明确的 PAN 似乎存在,有什么建议吗?
    【解决方案2】:

    虽然@adarsh-nanu 的回答提供了确切的 BER-TLV 规范,但我相信 @michael-mccauley 遇到的是 MagTek 对 TLV 标签的无效使用。实际上,我偶然发现了 IDTech VIVOpay 的这个确切场景,他们也使用了无效标签。

    我推出了自己的 TLV 解析例程,并在不符合 BER-TLV 标准时特别调用了不符合标准的标签来强制设置长度。请参阅下面的示例代码:

    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;
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      相关资源
      最近更新 更多