第二章:APDU通信协议基础

各位同学,今天我们来聊聊APDU通信协议。说实话,这是JavaCard开发中最基础、也最容易踩坑的部分。我刚开始接触智能卡时,就被APDU的格式搞得晕头转向——明明就那么几个字节,为什么能玩出这么多花样?

2.1 APDU命令结构

APDU全称是Application Protocol Data Unit,说白了就是应用层的数据交换单元。你想想看,卡片和读卡器之间要通信,总得有个约定好的格式吧?APDU就是这个约定。

一个命令APDU由两部分组成:头部(Header)体部(Body)。头部固定4个字节,体部则根据情况变化。

字节 名称 说明
CLA 指令类别 通常为0x00,表示ISO标准指令
INS 指令代码 比如0xA4表示SELECT,0xB0表示READ BINARY
P1 参数1 指令的具体参数
P2 参数2 与P1配合使用
Lc 数据长度 发送的数据字节数(可选)
Data 数据域 实际发送的数据(可选)
Le 期望响应长度 期望返回的数据字节数(可选)

嗯,这里要注意:Lc和Le不是同时出现的。它们的关系有点像跷跷板——有Lc就没Le,有Le就没Lc,或者两个都没有。

命令APDU的四种情况:

  • 情况1:CLA INS P1 P2 —— 无数据发送,无数据接收
  • 情况2:CLA INS P1 P2 Le —— 无数据发送,期望接收Le字节
  • 情况3:CLA INS P1 P2 Lc Data —— 发送Lc字节数据,无数据接收
  • 情况4:CLA INS P1 P2 Lc Data Le —— 发送数据,并期望接收Le字节

我个人习惯把情况1叫做"空手道"——什么都不带,什么都不拿。情况2是"空手去,满载归"。情况3是"带东西去,空手回"。情况4嘛,就是"带东西去,带东西回"。

2.2 APDU响应结构

响应APDU的结构就简单多了。它只有两部分:数据体状态字

响应APDU格式:
[Data] SW1 SW2

状态字SW1和SW2是两个字节,用来表示命令执行的结果。最常见的状态字是0x9000,表示一切正常。我在项目中遇到过最坑的情况就是——卡片返回了0x9000,但数据却是错的。后来才发现是APDU的Le字段写错了。

状态字 含义 我的经验
0x9000 正常执行 最常见的,但别太相信它
0x6A82 文件未找到 SELECT指令经常遇到
0x6985 条件不满足 安全状态不对,先验证PIN
0x6700 长度错误 Lc或Le写错了,我犯过好几次
0x6D00 INS不支持 指令代码没实现

避坑指南:我曾经花了一整天调试一个APDU,结果发现是Le字段写成了0x00。在T=0协议下,Le=0x00表示期望接收256字节,但在T=1协议下,Le=0x00表示不期望接收数据。这个差异让我吃了大亏。

2.3 T=0与T=1协议对比

T=0和T=1是ISO 7816-3中定义的两种传输协议。说白了,它们就是APDU在物理层上的"快递方式"。

T=0协议:字节传输协议。每个字节都需要握手确认。就像你寄快递,每走一步都要签收确认。效率低,但可靠性高。

T=1协议:块传输协议。把数据打包成块(Block)发送。就像你寄快递,一箱一箱地寄,每箱有个清单。效率高,但实现复杂。

我的建议:如果你在做简单的智能卡应用,比如门禁卡、公交卡,T=0就够用了。但如果你在做金融卡、SIM卡这种需要大量数据交换的应用,T=1是更好的选择。

特性 T=0 T=1
传输单位 字节 块(Block)
握手方式 每个字节都需要 每个块需要
数据吞吐量
实现复杂度 简单 复杂
错误处理 基本 完善(有重传机制)
典型应用 简单存储卡 金融卡、SIM卡

你想想看,为什么T=1协议会有重传机制?因为金融交易中,数据丢包可不是闹着玩的。我记得有一次帮客户调试POS机,发现T=0协议下偶尔会出现数据错位的问题,换成T=1后就再也没出现过。

2.4 核心知识体系

下面这张图是我自己整理的APDU通信协议知识体系,你可以把它当作学习地图。

APDU通信协议知识体系 APDU命令结构 • 头部:CLA, INS, P1, P2(固定4字节) • 体部:Lc, Data, Le(可选) • 四种情况:1/2/3/4 • 常见指令:SELECT, READ, WRITE • 注意:Lc和Le不能同时出现 APDU响应结构 • 数据体:返回的数据(可选) • 状态字:SW1 SW2(固定2字节) • 0x9000:正常执行 • 0x6A82:文件未找到 • 0x6985:条件不满足 传输协议对比 T=0 协议 • 字节传输,逐个握手 • 实现简单,可靠性高 • 适合简单应用 T=1 协议 • 块传输,效率高 • 有重传机制,更可靠 • 适合金融、SIM卡等 选择哪种协议,取决于你的应用场景和性能要求

这张图把APDU通信协议的核心内容都串起来了。左边是命令结构,右边是响应结构,下面是传输协议。我个人觉得,理解这三者的关系,就掌握了APDU通信的80%。

核心要点总结:

  • 命令APDU:CLA INS P1 P2 [Lc Data] [Le]
  • 响应APDU:[Data] SW1 SW2
  • T=0:字节级传输,简单可靠
  • T=1:块级传输,高效可靠
  • 状态字0x9000不代表数据一定正确

好了,APDU通信协议的基础就讲到这里。记住,纸上得来终觉浅,绝知此事要躬行。我建议你找个实际的智能卡,用APDU工具发几条命令试试,感受一下T=0和T=1的区别。嗯,实践出真知。

专注资料整理