日志文件格式解析:TLV格式详解

做EMV交易日志分析,绕不开一个东西——TLV。说白了,TLV就是数据在日志里的"包装方式"。我刚开始接触EMV时,看着日志里一串串十六进制数,头都大了。后来发现,只要搞懂TLV,日志就像一本打开的书。

TLV是Tag-Length-Value的缩写。每个数据元由三部分组成:标签(Tag)、长度(Length)、值(Value)。这个结构简单到令人发指,但威力巨大。

TLV基本结构:

+------+--------+--------+
| Tag  | Length | Value  |
| 1-2B | 1-3B   | 可变长  |
+------+--------+--------+

举个例子。你在日志里看到 9F02 06 000000001000,怎么拆?

  • Tag:9F02(2字节)——表示"交易金额"
  • Length:06(1字节)——后面跟着6字节数据
  • Value:000000001000(6字节)——金额是10.00元

嗯,就这么简单。但实际项目中,TLV会嵌套,会变长,会让人抓狂。我曾经在一个日志里看到7层嵌套的TLV,一层套一层,跟俄罗斯套娃似的。

BER-TLV编码规则

BER-TLV是EMV用的TLV变体。它比普通TLV多了一个"类型"的概念。BER-TLV的Tag分三类:

Tag类型 格式 说明
基本型 1字节(0x00-0x1F) 最常用,比如0x9F
构造型 1字节(0x20-0x3F) 包含子TLV,比如0x6F
私有型 2字节以上 发卡行自定义,比如0xDF8110

怎么判断一个Tag是基本型还是构造型?看最低位。如果最低位是1,就是构造型。比如0x6F(二进制0110 1111),最低位是1,说明它里面还包着其他TLV。

我的小技巧:解析BER-TLV时,先看Tag的bit0。如果是1,说明这个TLV是"容器",里面还有子TLV。我习惯用递归方式解析,遇到构造型就往下钻,直到遇到基本型为止。

Length字段也有讲究。如果长度值小于128,直接用1字节表示。如果大于等于128,第一个字节的最高位设为1,后面7位表示"后面还有几个字节表示长度"。

// 长度编码示例
长度=10(小于128)→ 0x0A
长度=200(大于128)→ 0x81 0xC8(0x81表示后面1字节,0xC8=200)
长度=1000 → 0x82 0x03 0xE8(0x82表示后面2字节,0x03E8=1000)

我记得有一次排查一个交易失败问题,日志里有个TLV的长度字段是0x81 0xFF,我一看就知道有问题——0xFF=255,但实际数据只有100字节。后来发现是终端固件bug,长度写错了。这种坑,没经验的人根本看不出来。

日志文件头结构

EMV交易日志的文件头,就像一本书的目录。不同厂商的日志格式不同,但核心结构大同小异。我以最常见的格式为例:

偏移 长度 字段 说明
0x00 4 文件标识 固定值,比如"EMVL"
0x04 2 版本号 比如0x0100表示1.0版
0x06 4 记录总数 日志里有多少条交易记录
0x0A 4 记录起始偏移 第一条记录从哪里开始
0x0E 18 保留字段 厂商自定义

文件头之后,就是一条条交易记录。每条记录也有自己的头部,包含时间戳、交易类型、终端号等信息。

注意:不同厂商的文件头结构差异很大。我见过某厂商把记录总数放在偏移0x20处,也见过用ASCII字符串做文件标识的。做取证分析时,第一步就是确认文件头格式,别想当然。

数据元标识符(DE)解析

数据元标识符(DE)是EMV交易日志里的"身份证"。每个DE都有一个编号,比如DE 4表示交易金额,DE 14表示有效期。ISO 8583标准定义了上百个DE,但EMV交易常用的就二三十个。

我整理了一份常用DE清单,做日志分析时经常用到:

DE编号 名称 格式 长度
DE 2 主账号(PAN) LLVAR 变长,最多19位
DE 4 交易金额 N12 12位数字
DE 11 系统跟踪号 N6 6位数字
DE 14 有效期 N4 YYMM格式
DE 22 服务点输入方式 N3 3位数字
DE 35 磁道2数据 LLVAR 变长
DE 55 IC卡数据 LLLVAR 变长,包含TLV

这里有个关键点——DE 55。它里面装的是IC卡返回的TLV数据。做EMV交易日志分析,DE 55是重中之重。我见过太多人只盯着DE 4看金额,忽略了DE 55里的认证结果,结果漏掉了关键证据。

实战案例:有一次我分析一笔争议交易,持卡人说没做过这笔消费。日志里DE 4显示金额5000元,DE 55里的9F27(密码分析结果)显示"脱机PIN验证失败"。这说明交易没通过密码验证,但终端还是完成了交易。这个DE 55里的TLV数据,成了定案的关键证据。

解析DE时,要注意格式类型:

  • 定长格式:直接按固定长度读取,比如DE 4固定12位
  • LLVAR:前2位是长度,后面是数据,比如DE 2
  • LLLVAR:前3位是长度,后面是数据,比如DE 55

LLVAR的"LL"表示长度字段占2个字节,LLLVAR的"LLL"表示占3个字节。这个细节容易搞混。我刚开始做时,把DE 55当成LLVAR解析,结果数据全乱了。后来才发现是LLLVAR,多了一个字节的长度指示。

SVG知识结构图

下面这张图,是我梳理的日志文件解析知识体系。你一看就明白各模块之间的关系。

EMV交易日志解析知识体系 日志文件解析 TLV格式详解 BER-TLV编码规则 日志文件头结构 数据元标识符(DE)解析 Tag-Length-Value 嵌套结构 基本型/构造型 长度编码规则 文件标识/版本 记录偏移 DE编号映射 LLVAR/LLLVAR 四个核心模块相互关联,DE 55是TLV和DE解析的交汇点

这张图把日志解析拆成四个模块。TLV格式是基础,BER-TLV是具体编码规则,文件头告诉你数据怎么组织,DE解析则是把数据翻译成业务含义。四个模块缺一不可。

我的建议:做日志分析时,先看文件头确认版本和记录数,然后定位到DE 55提取TLV数据,再用BER-TLV规则解析。这个流程我用了十年,没出过岔子。

最后说一句,日志解析是个细致活。一个字节的偏差,可能导致整条记录解析失败。我习惯在解析前先做一次"格式校验",确认文件头、记录长度、TLV结构都符合预期。这步做好了,后面就顺了。


公众号:蓝海资料掘金营,微信deep3321