← 返回知识库

智能卡APDU指令详解:从入门到实战

约 3500 字 | 智能卡开发基础 | 2026-07

什么是 APDU?

APDU(Application Protocol Data Unit,应用协议数据单元)是智能卡与读卡器之间通信的核心协议。无论是银行卡、SIM 卡、身份证还是门禁卡,所有智能卡应用层的通信都通过 APDU 指令完成。理解 APDU 是智能卡开发的第一道门槛。

ISO 7816-4 标准定义了 APDU 的格式和交换机制。一条完整的 APDU 交互由命令 APDU(C-APDU)响应 APDU(R-APDU)组成。读卡器发送 C-APDU,卡片处理后返回 R-APDU。

C-APDU 命令结构

一条标准的命令 APDU 由必选头部(4字节)可选体部(可变长)组成:

字段长度含义说明
CLA1 byte指令类别标识指令类型,如 0x00=ISO标准、0x80=GP规范、0xA0=应用私有
INS1 byte指令代码具体操作,如 0xA4=SELECT、0xB0=READ BINARY、0xB2=READ RECORD
P11 byte参数 1指令参数,含义取决于 INS
P21 byte参数 2指令参数,含义取决于 INS
Lc0/1/3 bytes数据域长度命令数据域的长度(0 表示无数据域)
DataLc bytes命令数据发送给卡片的实际数据
Le0/1/2/3 bytes期望响应长度期望卡片返回的最大字节数(0x00 表示 256)

根据 Lc 和 Le 是否出现,APDU 分为四种 Case:

Case结构典型场景
Case 1CLA INS P1 P2无数据交换,如卡片复位后的首次选择
Case 2CLA INS P1 P2 Le从卡片读数据,如 READ BINARY
Case 3CLA INS P1 P2 Lc Data向卡片写数据,如 PUT DATA
Case 4CLA INS P1 P2 Lc Data Le先写后读,如 SELECT + 获取 FCI

R-APDU 响应结构

卡片返回的响应 APDU 包含两部分:

字段长度含义
Data可变 (0~Le)响应数据体(可选)
SW2 bytes状态字(SW1 + SW2)

状态字 SW1-SW2 是判断指令执行结果的关键:

SW1 SW2含义
90 00指令执行成功
61 XX还有 XX 字节数据待取,需发 GET RESPONSE
6A 82文件/应用未找到
69 84数据无效(如密钥已锁定)
69 85使用条件不满足(如未通过安全验证)
6B 00P1/P2 参数错误(偏移量越界)
6D 00INS 指令不支持
6E 00CLA 指令类别不支持
69 82安全状态不满足(需先 VERIFY PIN)
调试技巧:如果返回 6A 82,优先检查文件 ID 是否正确;返回 69 85 大概率是卡没选上或者没做安全认证。90 00 不代表万事大吉——SW=9000 只是说"指令格式正确、执行完成",数据本身的语义验证需要你自己做。

常见 APDU 命令速查

SELECT — 选择应用/文件 (INS=0xA4)

这是最常用的 APDU 命令。通过 AID(应用标识符)或文件 ID 选择卡片上的目标应用或文件。

# 通过 AID 选择应用 (P1=04 表示按名称选择)
00 A4 04 00 08 A0 00 00 00 03 00 00 00 00

# 通过文件 ID 选择 EF (P1=00 表示按文件 ID 选择)
00 A4 00 00 02 3F 00

# 选择 MF(主文件,卡根目录)
00 A4 00 00 02 3F 00 00

SELECT 成功后会返回 FCI(文件控制信息),包含文件类型、访问权限等。FCI 是 TLV 编码的,可以用卡智通的 TLV 解析器 查看结构。

READ BINARY — 读取透明文件 (INS=0xB0)

从透明结构 EF(二进制文件)中读取指定偏移量的数据:

# 从偏移 0x0000 读取 16 字节
00 B0 00 00 10

GET DATA — 获取卡片数据 (INS=0xCA)

获取卡片出厂信息、CPLC 数据、序列号等:

# 获取卡序列号 (P1P2=9F7F)
80 CA 9F 7F 00

VERIFY — 验证 PIN 码 (INS=0x20)

# 验证 PIN(P2=01 表示 PIN1, Lc=06 表示 6 位 PIN)
00 20 00 01 06 31 32 33 34 35 36

T=0 与 T=1 传输协议

ISO 7816-3 定义了两种底层传输协议:

特性T=0T=1
传输单位字节数据块(Block)
错误检测奇偶校验LRC/CRC 校验
Case 4 支持需发两次(先发 Lc+Data,再发 GET RESPONSE)原生支持
传输效率较低较高(适合大块数据传输)
应用银行卡、SIM 卡eSIM、高性能安全芯片

接触式智能卡通常两种都支持,通过 ATR(Answer To Reset)中的 TA2 字节协商选择。开发时注意 T=0 协议下 Case 4 指令需要额外处理 GET RESPONSE 流程。

实战:用 APDU 读取银行卡信息

以下是一个完整的交互序列,展示如何通过 APDU 读取一张 PBOC 借记卡的基本信息:

# 1. 选择支付系统环境 (PSE)
00 A4 04 00 0E 31 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
→ 6F 2A 84 0E ... 90 00  # 返回 FCI,SW=9000 成功

# 2. 选择应用 (AID: A000000333010101 = PBOC借记)
00 A4 04 00 07 A0 00 00 00 03 33 01 01 01 00
→ 6F 40 ... 90 00

# 3. 读取应用数据 (GPO/GET PROCESSING OPTIONS)
80 A8 00 00 02 83 00 00
→ 77 0A ... 90 00

# 4. 读取卡号记录 (READ RECORD)
00 B2 01 14 00
→ 70 1A ... 5A 08 62 24 56 78 12 34 56 78 ... 90 00
# 标签 5A 包含主账号 (PAN),值 6224567812345678
动手试试:拿到上面的响应数据后,可以用卡智通的 TLV 解析器 把 BER-TLV 结构拆解为可读的标签树,也可以用 CRC 计算器 验证数据的完整性校验。

非接式通信:APDU 在 NFC 中的应用

在非接触式场景(NFC/ISO 14443)中,APDU 同样适用。区别在于底层物理层不同——非接卡通过射频磁场供电和通信,上层 ISO 7816-4 的 APDU 结构保持不变。这意味着同一张双界面卡(如银联闪付卡),接触式和非接式走的是同一套 APDU——切换物理接口不影响应用层代码。

常见问题

为什么 SELECT 返回 6A82?

最常见的原因:AID 拼写错误或长度不匹配。AID 由 RID(5字节,需向 ISO 申请)和 PIX(可变长,厂商定义)组成。检查长度字节 Lc 是否等于 AID 的实际长度。

SW1=61 是什么意思?

这不是错误!61 XX 表示卡片有 XX 字节数据等你来取。发 00 C0 00 00 XX(GET RESPONSE)获取数据。T=0 协议下 Case 4 指令最常遇到这种情况。

如何判断卡片是否支持某个 AID?

先通过 PSE(Payment System Environment)或 PPSE(Proximity PSE,AID=325041592E5359532E4444463031)查询卡片支持的应用列表。大部分支付卡都支持这个查询。

相关工具:处理 APDU 数据常用的在线工具

📋 TLV 解析器 🏷️ ASN.1 解析器 🔢 CRC 计算器 💳 Luhn 校验 📝 Base64 编解码 🏦 EMV 标签查询 🔍 AID 查询