日志文件格式解析: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知识结构图
下面这张图,是我梳理的日志文件解析知识体系。你一看就明白各模块之间的关系。
这张图把日志解析拆成四个模块。TLV格式是基础,BER-TLV是具体编码规则,文件头告诉你数据怎么组织,DE解析则是把数据翻译成业务含义。四个模块缺一不可。
我的建议:做日志分析时,先看文件头确认版本和记录数,然后定位到DE 55提取TLV数据,再用BER-TLV规则解析。这个流程我用了十年,没出过岔子。
最后说一句,日志解析是个细致活。一个字节的偏差,可能导致整条记录解析失败。我习惯在解析前先做一次"格式校验",确认文件头、记录长度、TLV结构都符合预期。这步做好了,后面就顺了。
公众号:蓝海资料掘金营,微信deep3321