APDU命令大全:智能卡APDU指令集完整参考
目录
- 一、APDU命令基础
- 二、APDU命令格式与结构
- 三、CLA指令类别编码表
- 四、INS指令代码完整列表
- 五、SELECT命令详解
- 六、READ BINARY / UPDATE BINARY命令
- 七、READ RECORD / APPEND RECORD命令
- 八、VERIFY命令详解
- 九、认证命令(INTERNAL / EXTERNAL AUTHENTICATE)
- 十、安全操作命令(GET CHALLENGE / MANAGE CHANNEL)
- 十一、状态字SW1 SW2完整对照表
- 十二、APDU四种子类型(Case 1~4)
- 十三、扩展APDU与链式传输
- 十四、EMV专用APDU命令
- 十五、APDU命令完整示例
一、APDU命令基础
APDU命令(Application Protocol Data Unit,应用协议数据单元)是ISO7816-4标准定义的智能卡通信协议核心。APDU是终端(读卡器)与智能卡之间交换信息的基本单位。理解APDU命令格式、APDU指令集和APDU状态字,是智能卡应用开发的基础技能。
在ISO7816 APDU体系中,通信永远是"命令-响应"模式:终端发送命令APDU(Command APDU),卡片处理后返回响应APDU(Response APDU)。所有APDU指令都由5字节的强制头和可选的数据体组成。
APDU与ISO7816的关系
APDU定义在ISO7816-4(组织、安全和命令)中。要完整理解APDU在智能卡协议栈中的位置,请先阅读ISO7816完整教程,了解从物理层到应用层的完整技术栈。
二、APDU命令格式与结构
命令APDU(Command APDU)结构如下:
命令APDU = CLA + INS + P1 + P2 + [Lc + Data] + [Le]
CLA (1字节): Class byte,指令类别
INS (1字节): Instruction byte,指令代码
P1 (1字节): Parameter 1,参数1
P2 (1字节): Parameter 2,参数2
Lc (0/1/3字节): Length of Command Data,命令数据长度
Data (变长): Command Data,命令数据字段
Le (0/1/3字节): Length of Expected Response Data,期望响应数据长度
响应APDU(Response APDU)结构如下:
响应APDU = [Response Data] + SW1 + SW2
Response Data (变长): 响应数据体(可选,仅在命令成功且有数据返回时存在)
SW1 (1字节): Status Word 1,状态字节1
SW2 (1字节): Status Word 2,状态字节2
# 最常用的成功状态:SW1 SW2 = 90 00(命令成功完成)
三、CLA指令类别编码表
CLA字节定义了APDU指令的类别和逻辑通道。以下是ISO7816 CLA编码的完整说明:
| CLA值 | 含义 | 说明 |
|---|---|---|
00 | ISO 7816标准指令 | 无安全消息,通道0 |
04 | ISO 7816标准指令 + 通道4 | 逻辑通道4上的标准指令 |
0C | ISO 7816标准指令 + 安全消息 | 使用安全消息(SM)保护的标准指令 |
10~7F | 保留(Reserved) | 保留给未来ISO扩展 |
80~FE | 私有/厂商自定义 | 发卡方或应用自行定义的私有指令 |
FF | 保留用于协议类型选择 | PPS(Protocol and Parameter Selection) |
四、INS指令代码完整列表
以下是ISO7816-4标准APDU指令集中定义的所有INS指令代码:
| INS代码 | 指令名称 | 功能说明 | 常用场景 |
|---|---|---|---|
0E | ERASE BINARY | 擦除透明EF中指定偏移的数据 | 数据清除 |
20 | VERIFY | 验证PIN码或口令 | 持卡人身份认证、PIN校验 |
21 | VERIFY(带状态) | 验证并返回剩余尝试次数 | PIN重试管理 |
22 | MANAGE SECURITY ENVIRONMENT | 管理安全环境(MSE) | 设置密钥引用、算法参数 |
24 | CHANGE REFERENCE DATA | 修改引用数据(PIN修改) | 改密操作 |
26 | DISABLE VERIFICATION REQUIREMENT | 禁用PIN验证要求 | 关闭某些操作的PIN保护 |
28 | ENABLE VERIFICATION REQUIREMENT | 启用PIN验证要求 | 开启某些操作的PIN保护 |
2A | PERFORM SECURITY OPERATION | 执行安全操作(PSO) | 数字签名、哈希计算、签名验证 |
2C | RESET RETRY COUNTER | 重置PIN重试计数器 | 使用PUK解锁PIN |
44 | ACTIVATE FILE | 激活文件 | 文件生命周期管理 |
46 | GENERATE ASYMMETRIC KEY PAIR | 生成非对称密钥对 | RSA/ECC密钥对生成 |
47 | MANAGE CHANNEL | 管理逻辑通道 | 打开/关闭逻辑通道 |
70 | MANAGE CHANNEL(非接触版) | 接触式/非接触式通道管理 | NFC非接触APDU通道 |
82 | EXTERNAL AUTHENTICATE | 外部认证 | 终端认证卡片、双向认证 |
84 | GET CHALLENGE | 获取随机数 | 防重放攻击、会话密钥生成 |
87 | GENERAL AUTHENTICATE | 通用认证 | 灵活认证框架,如EMV SDA/DDA/CDA |
88 | INTERNAL AUTHENTICATE | 内部认证 | 卡片端签名认证 |
A4 | SELECT | 选择文件/应用 | 选择MF、DF、ADF、EF及应用(最常用) |
B0 | READ BINARY | 读取透明EF二进制数据 | 读取智能卡数据 |
B2 | READ RECORD | 读取记录文件中的记录 | 读取EMV标签数据 |
C0 | GET RESPONSE | 获取响应(T=0协议专用) | T=0协议下获取大于256字节的响应 |
C2 | ENVELOPE | 封装命令 | 在安全消息中封装其他APDU |
CA | GET DATA | 读取数据对象 | 按Tag读取特定数据对象 |
D0 | WRITE BINARY | 写入透明EF(一次性写入) | 数据写入 |
D2 | WRITE RECORD | 写入记录(一次性) | 记录写入 |
D6 | UPDATE BINARY | 更新透明EF中的数据 | 修改卡内数据(应用数据更新) |
DA | PUT DATA | 写入/更新数据对象 | 按Tag写入特定数据对象 |
DC | UPDATE RECORD | 更新记录文件中的记录 | 更新卡片记录 |
E0 | CREATE FILE | 创建文件 | 创建DF/EF |
E2 | APPEND RECORD | 追加记录 | 在线性记录文件末尾追加新记录 |
E4 | DELETE FILE | 删除文件 | 删除DF/EF |
E6 | TERMINATE DF | 终止DF | 应用终止(不可逆) |
E8 | TERMINATE CARD USAGE | 终止卡片使用 | 卡片作废(不可逆) |
F2 | MANAGE SECURITY ENVIRONMENT(备用) | MSE变体命令 | 安全环境管理的扩展操作 |
五、SELECT命令详解
SELECT命令(INS=A4)是APDU指令集中使用频率最高的命令。SELECT用于选择智能卡上的文件(MF/DF/EF)或应用(通过AID)。
SELECT 命令格式:
CLA: 00(标准)
INS: A4
P1: 选择方式
04 = 通过DF名称(AID)选择
00 = 通过文件标识符(FID)选择
01 = 选择当前DF的子DF
02 = 选择当前DF下的EF
03 = 选择当前MF下的子元素
P2: 选择选项
00 = 第一个或唯一匹配
02 = 下一个匹配(用于AID有多个实例时)
0C = 不返回FCI数据
Data: 文件标识符(2字节)或 AID(5~16字节)
Le: 00(期望返回FCI/FCP模板)
SELECT命令示例:
# 选择MF(主文件)
00 A4 00 00 02 3F 00 00
# 通过AID选择EMV支付应用(Visa)
00 A4 04 00 07 A0 00 00 00 03 10 10 00
# 选择当前DF下的EF(文件ID=0x0015)
00 A4 02 00 02 00 15 00
# 获取下一个匹配的AID实例
00 A4 04 02 07 A0 00 00 00 03 10 10 00
六、READ BINARY / UPDATE BINARY命令
READ BINARY(INS=B0)用于读取透明EF(二进制文件)中的数据。需要先用SELECT选择目标文件。
READ BINARY 命令格式:
CLA: 00(标准)或 0C(安全消息)
INS: B0
P1: 偏移量高位(SFI在bit7-5,如使用SFI模式则P1的第7位=1)
P2: 偏移量低位(从0开始的字节偏移)
Le: 要读取的字节数(00=256字节)
# 示例:从偏移0读取16字节
00 B0 00 00 10
UPDATE BINARY(INS=D6)用于更新透明EF中的指定偏移处的数据。执行前需要满足该文件的安全访问条件(如PIN验证)。
UPDATE BINARY 命令格式:
CLA: 00 或 0C(安全消息)
INS: D6
P1: 偏移量高位(可使用SFI模式)
P2: 偏移量低位
Lc: 数据长度
Data: 要写入的数据
# 示例:在偏移8处写入4字节数据
00 D6 00 08 04 AA BB CC DD
七、READ RECORD / APPEND RECORD命令
READ RECORD(INS=B2)用于读取记录EF中的记录。记录文件每条记录等长,通过记录号或记录标识符定位。
READ RECORD 命令格式:
CLA: 00
INS: B2
P1: 记录号(1-based)或 00(由P2中的SFI指定)
P2: 读取模式:
bit7-3: SFI(短文件标识符,0-30)
bit2-0: 100 = P1指定记录号
Le: 期望长度(00=读取整条记录)
# 示例:读取SFI=1的第3条记录
00 B2 03 1C 00
八、VERIFY命令详解
VERIFY命令(INS=20)用于验证PIN码或口令。这是智能卡安全体系中最常用的认证命令。
VERIFY 命令格式:
CLA: 00
INS: 20
P1: 00(传输PIN数据)
P2: PIN引用号(指示验证哪个PIN,如01=持卡人PIN,02=管理员PIN)
Lc: PIN数据长度
Data: PIN数据(通常是ASCII或二进制格式的持卡人输入的密码)
# 示例:验证引用号为01的PIN(6位ASCII PIN: 123456)
00 20 00 01 06 31 32 33 34 35 36
# 验证后可能的响应:
# 90 00 = PIN验证成功
# 63 Cx = PIN错误,剩余x次尝试机会(x=0时已锁定)
九、认证命令
INTERNAL AUTHENTICATE(INS=88)和EXTERNAL AUTHENTICATE(INS=82)是双向认证的核心命令。
INTERNAL AUTHENTICATE:终端发送随机挑战数据给卡片,卡片使用内部私钥签名后返回。用于终端验证卡片的真实性。
# 内部认证示例:发送8字节挑战,获取签名
00 88 00 00 08 11 22 33 44 55 66 77 88 00
EXTERNAL AUTHENTICATE:终端用外部密钥加密挑战数据后发送给卡片验证。用于卡片验证终端的合法性。常用于安全域管理。
# 外部认证:发送加密的认证数据
00 82 00 00 08 [8字节加密认证码]
十、安全操作命令
GET CHALLENGE(INS=84)获取卡内生成的随机数,用于防重放攻击:
# 请求8字节随机数
00 84 00 00 08
MANAGE CHANNEL(INS=47)管理逻辑通道,允许在一个物理连接中同时运行多个应用:
# 打开逻辑通道
00 47 00 00 01 [AID] 00
# 关闭逻辑通道(通道号在P2中)
00 47 80 01 00
PERFORM SECURITY OPERATION(PSO,INS=2A)执行数字签名、哈希计算等安全操作:
# PSO计算数字签名
00 2A 9E 9A 20 [待签名数据的SHA-256哈希值] 00
十一、状态字SW1 SW2完整对照表
APDU状态字(SW1 SW2)表示命令的执行结果。SW1 SW2=9000是正常完成的标志。以下是常用状态字:
| SW1 | SW2 | 含义 | 常见原因 |
|---|---|---|---|
90 | 00 | 命令成功完成 | 正常返回 |
61 | XX | 命令已处理,有XX字节数据可获取 | T=0协议下需用GET RESPONSE取数据 |
62 | 00 | 警告:返回的数据可能已损坏 | |
62 | 81 | 返回数据可能不完整 | 部分数据被截断 |
62 | 82 | 在达到Le字节前文件已结束 | 读取超出文件范围的偏移 |
62 | 83 | 选中的文件/记录被停用 | 文件已锁定或废弃 |
62 | 84 | FCI格式不符合ISO7816-4标准 | |
63 | 00 | 认证失败 | PIN验证失败 |
63 | CX | 验证失败,剩余x次尝试 | X=0时PIN已锁定(需PUK解锁) |
64 | 00 | 状态标志位非易失性存储器变化 | |
65 | 00 | 状态标志位变化 | |
65 | 81 | 存储器错误(写入失败) | EEPROM/Flash写入出错 |
67 | 00 | 长度错误(Lc/Le不正确) | 数据长度字段与命令不匹配 |
68 | 00 | CLA不支持的功能 | |
68 | 81 | 不支持逻辑通道 | |
68 | 82 | 不支持安全消息(SM) | |
69 | 00 | 命令不被允许 | |
69 | 81 | 命令与文件结构不兼容 | 用READ BINARY读记录文件 |
69 | 82 | 安全状态不满足 | 未验证PIN或未通过认证 |
69 | 83 | 认证方法被阻塞 | PIN已锁定 |
69 | 84 | 引用的数据无效 | 引用的密钥/PIN不存在 |
69 | 85 | 使用条件不满足 | 时间段限制、次数限制 |
69 | 86 | 命令不允许(无当前EF) | 需先SELECT一个文件 |
6A | 00 | P1/P2参数错误 | |
6A | 80 | 数据字段参数不正确 | |
6A | 81 | 功能不支持 | 卡片不支持此INS或操作 |
6A | 82 | 文件未找到 | FID/AID无效或不存在 |
6A | 83 | 记录未找到 | 记录号超出范围 |
6A | 84 | 存储器空间不足 | 文件已满 |
6A | 86 | P1/P2不正确 | |
6A | 88 | 引用的数据(密钥等)未找到 | 安全环境引用不存在的密钥 |
6B | 00 | 偏移超出EF范围 | READ BINARY偏移量检查失败 |
6C | XX | Le错误:正确的Le=XX | 终端应以XX重新发送命令 |
6D | 00 | 不支持的INS指令代码 | 卡片不支持此命令 |
6E | 00 | 不支持的CLA类别 | |
6F | 00 | 检查错误/内部异常 | 卡片内部错误(应尝试复位) |
十二、APDU四种子类型(Case 1~4)
根据数据字段的组合,APDU命令分为四种Case类型:
| Case | 结构 | 说明 | 示例命令 |
|---|---|---|---|
| Case 1 | CLA INS P1 P2 | 无命令数据,无响应数据 | DELETE FILE等管理命令 |
| Case 2 | CLA INS P1 P2 Le | 无命令数据,有响应数据 | READ BINARY、READ RECORD |
| Case 3 | CLA INS P1 P2 Lc Data | 有命令数据,无响应数据 | UPDATE BINARY、WRITE RECORD |
| Case 4 | CLA INS P1 P2 Lc Data Le | 有命令数据,有响应数据 | SELECT、INTERNAL AUTHENTICATE |
十三、扩展APDU与链式传输
当数据超过256字节时,使用扩展APDU(Extended APDU)。扩展APDU的Lc和Le字段使用3字节编码(而非1字节),最大可支持65535字节的数据传输。
T=0协议本身不支持扩展APDU,但通过链式传输(Command Chaining)机制可以实现大数据传输:CLA的低位bit5(0x10)置1表示"后面还有更多数据"。T=1协议原生支持扩展长度和链式传输。
十四、EMV专用APDU命令
EMV(Europay Mastercard Visa)支付规范在ISO7816-4的基础上定义了额外的APDU命令:
| 命令名 | INS | 功能 | 说明 |
|---|---|---|---|
| GET PROCESSING OPTIONS (GPO) | A8 | 获取处理选项 | EMV交易第一步核心命令 |
| GENERATE AC | AE | 生成应用密文 | 卡片风险评估和密文生成 |
| GET DATA | CA | 读取数据(EMV扩展) | 读取ATC、上次在线AT等动态数据 |
| READ RECORD | B2 | 读取记录(同ISO7816) | 读取AFL指定的记录 |
| VERIFY | 20 | PIN验证(同ISO7816) | 联机/脱机PIN验证 |
十五、APDU命令完整示例
以下是一个完整的EMV交易APDU命令序列示例,展示从卡片激活到完成交易的典型流程:
# ====== 步骤1: 复位获取ATR ======
复位 → 卡片返回 ATR: 3B 9F 96 80 1F C7 80 31 E0 73 ...
# ====== 步骤2: 选择支付应用 ======
→ 00 A4 04 00 07 A0 00 00 00 03 10 10 00
← 6F 1A ... 90 00 (FCI模板,应用选择成功)
# ====== 步骤3: 获取处理选项(GPO)=====
→ 80 A8 00 00 02 83 00 00
← 77 0E 82 02 19 00 94 08 08 01 01 00 10 01 01 00 90 00
# AFL=08010100 10010100: 需读取两条记录
# ====== 步骤4: 读取应用数据记录 ======
→ 00 B2 01 1C 00
← 70 5D ... (包含PAN、有效期、Track 2等效数据) ... 90 00
→ 00 B2 02 1C 00
← 70 4A ... (包含公钥证书、发卡行数据) ... 90 00
# ====== 步骤5: 内部认证(可选,SDA/DDA)=====
→ 00 88 00 00 08 [8字节随机挑战] 00
← [签名的动态应用数据] 90 00
# ====== 步骤6: 生成应用密文(GENERATE AC)=====
→ 80 AE 80 00 1D [CDOL1数据] 00
← 77 0E ... [密文信息数据+应用密文] ... 90 00
学习路径建议
APDU命令是智能卡开发的核心技能。建议学习路径:ISO7816完整教程(理解协议基础)→ APDU命令大全(本文,掌握命令细节)→ TLV格式详解(数据编码)→ EMV Tag详解(支付应用实战)。