如何用Flutter的nfc_manager读取ISO 14443-3A卡?含handleIso7816用法
处理ISO 14443-3A NFC卡的ISO7816指令与transceive方法解析
一、handleIso7816方法实现思路
ISO 14443-3A是NFC卡的底层通信协议,ISO7816是应用层指令规范,要读取卡中数据,核心是通过Iso7816Tag实例发送符合ISO7816标准的APDU指令:
转换标签实例:从识别到的
NfcTag中提取Iso7816Tag对象,这是处理ISO7816指令的入口:final iso7816Tag = Iso7816Tag.from(tag);若转换失败,说明当前标签不支持ISO7816指令集。
构造APDU指令:APDU是ISO7816定义的指令格式,由
CLA(指令类)、INS(指令码)、P1/P2(参数)、Lc(数据长度)、Data(指令数据)、Le(期望响应长度)组成。常见指令示例:- 选择应用(SELECT):
[0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00](后7字节为应用AID) - 读二进制数据(READ BINARY):
[0x00, 0xB0, 0x00, 0x00, 0x10](读取偏移0x00开始的16字节)
- 选择应用(SELECT):
发送指令并处理响应:通过
transceive方法发送APDU,接收卡片返回的响应数据。
二、transceive()方法的核心逻辑
transceive(List<int> command)是NFC标签的双向通信方法,核心逻辑:
- 输入:必须是符合ISO7816规范的APDU指令字节数组
- 输出:卡片返回的响应字节数组,最后两个字节是状态码(如
0x9000表示指令执行成功,0x6A82表示未找到应用) - 异常处理:通信超时、卡片断开、指令格式错误等场景会抛出异常,必须用
try-catch捕获
完整实现示例
import 'package:nfc_manager/nfc_manager.dart'; Future<void> handleIso7816Tag(NfcTag tag) async { final iso7816Tag = Iso7816Tag.from(tag); if (iso7816Tag == null) { print('当前标签不支持ISO7816指令'); return; } try { // 发送SELECT指令选择目标应用 final selectApdu = [0x00, 0xA4, 0x04, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00]; final selectResponse = await iso7816Tag.transceive(selectApdu); // 检查响应状态码是否为成功(0x9000) final statusCode = selectResponse.sublist(selectResponse.length - 2); if (statusCode[0] == 0x90 && statusCode[1] == 0x00) { // 发送READ BINARY指令读取数据 final readApdu = [0x00, 0xB0, 0x00, 0x00, 0x10]; // 读取偏移0x00开始的16字节 final readResponse = await iso7816Tag.transceive(readApdu); // 分离有效数据和状态码 final data = readResponse.sublist(0, readResponse.length - 2); final readStatus = readResponse.sublist(readResponse.length - 2); print('读取到的数据(十六进制): ${_bytesToHex(data)}'); print('读取响应状态码: ${_bytesToHex(readStatus)}'); } else { print('SELECT指令执行失败,状态码: ${_bytesToHex(statusCode)}'); } } catch (e) { print('NFC通信异常: $e'); } } // 辅助方法:将字节数组转为十六进制字符串 String _bytesToHex(List<int> bytes) { return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(' '); }
关键注意事项
- APDU指令需匹配你的卡片实际应用AID,不同卡片的AID可能不同,需参考卡片技术文档
- 部分卡片可能需要先进行认证操作才能读取数据,需根据卡片协议添加对应指令
- 移动端NFC操作需在AndroidManifest.xml(Android)或Info.plist(iOS)中配置NFC权限及相关权限声明
内容的提问来源于stack exchange,提问作者Bankole emmanuel
相关产品推荐
相关产品推荐

