每笔 DE55 里都埋着一个两字节的数字,解析工具都会打出来、却很少有人多看一眼:应用交易计数器(ATC)。卡片每发起一笔交易就给它加一。就这么个不起眼的习惯,让每笔密文都成了一次性的——也顺手给了发卡方一个成本最低的克隆卡探测器。
ATC 是芯片内部维护的 16 位无符号计数器,每个卡片应用各有一个。每执行一次 GENERATE AC——不管这笔最后是批准还是拒绝、联机还是脱机——卡片就加一。它不会减、外部也没法重置,只有一个方向:往上,直到 65535 用完为止。004B 的意思很朴素:这是该应用的第 75 次交易尝试。
这句话里有两个词,后面全靠它们撑着。每个应用:双 AID 的卡有两个互不相干的计数器,拿 A 应用的 ATC 去对 B 应用的历史,比出来的只能是乱码。尝试:被拒绝的、半途而废的交易同样消耗号码——所以发卡方看到的序列,天生就该有窟窿。
每笔芯片交易都带一个应用密文(标签 9F26,见 EMV 标签查询)——卡片用密钥对交易数据算出来的 MAC。金额、日期、终端的不可预知数都是输入,但 ATC 的角色更特殊:在常见的派生方案里,会话密钥本身就是拿 ATC 派生的,每笔交易连密钥都不一样。第 75 次尝试的密文,用的是只有第 75 次才会有的材料。
这就把截获了一笔完整授权报文的攻击者堵死了。原样重发,发卡方会第二次收到 ATC = 75,立刻起疑;把 ATC 改成 76 再发,密文又对不上号——重算密文需要那把从不出芯片的密钥。两条路都断在发卡方主机上,不需要任何网络层的防护。计数器加上带密钥的 MAC,等于给每笔授权报文都盖了「仅此一次」的戳。
卡片里还有第二个寄存器:最近一次联机授权成功那笔交易的 ATC,以标签 9F13(Last Online ATC Register,上次联机 ATC)暴露出来。终端在风险管理时读出它,做一个减法:
9F36 − 9F13 = 发卡方上次见到这张卡之后,连续脱机了多少笔
EMV 给每张卡设了连续脱机的下限和上限:差值过了下限,终端就该把交易送联机;过了上限,卡片应当直接脱机拒绝。这两道检查在 TVR 字节 4 里各占一个位(「超过连续脱机交易下限 / 上限」)。
拿数字算一遍:9F36 = 004B、9F13 = 0047,即 75 − 71 = 4——上次联机之后又脱机跑了 4 笔。把这两个值贴进 ATC 解析工具,十六进制转十进制和差值它都替你算好。
注意这里的分工:终端对这张卡没有记忆,所以才需要 9F13;发卡方根本用不着 9F13——它手里有更好的东西:自己的授权流水。
每笔联机授权都会送来一个新的 9F36。发卡方翻出自己记录里该应用的最高 ATC,只问一个问题:新值落在记录值的哪一侧、离多远?一条数轴就能把所有情况摆完:
把数轴上的三种异常逐个念出来:
| 形态 | 通常意味着什么 |
|---|---|
| 重复值(又见 75) | 同一个计数值出现了两次。在实时授权流里,这是被重放的密文,或是按卡片快照复制出来的克隆卡;在清算文件里也可能只是老实的重复入账——升级之前先看记录的其它字段。 |
| 大幅跳变(97) | 中间 22 次尝试发卡方一次都没见过。多数情况是良性的:交通卡式配置的长脱机序列、脱机拒绝、终端压根没上送。但要是再叠加一个反常的地点或金额,它也可能是一张已在别处消费多时的卡第一次联机现身。 |
| 回退(72) | 芯片不会倒着数。实时授权里出现低于记录最高值的 ATC,意味着报文来自另一块芯片——同一个卡号、同一套密钥的第二张卡,也就是教科书式的克隆卡特征;发卡方主机日志里的「ATC mismatch / ATC out of range」拒绝,多数就是这条规则开的枪。唯一的良性版本在清算侧:脱机交易晚几天才入账,乱序是常态。 |
不少发卡方的风控规则会在 ATC 落到窗口外时直接拒绝——分析师在日志里看到的 ATC mismatch 类拒绝就是这么来的。但这条规则证明了什么、没证明什么,值得说清楚。ATC 不连续,有一堆无辜的解释:
所以孤立的跳号只是噪声。真正的信号,是正常卡在授权流里结构上做不出来的两件事:同一个值出现两次,以及值往回走。见跳号就拒的主机,收获的多半是通勤族的误伤;对重复和回退视而不见的主机,则放过了克隆卡唯一被迫露馅的字段。