You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Flutter的nfc_manager读取ISO 14443-3A卡?含handleIso7816用法

处理ISO 14443-3A NFC卡的ISO7816指令与transceive方法解析

一、handleIso7816方法实现思路

ISO 14443-3A是NFC卡的底层通信协议,ISO7816是应用层指令规范,要读取卡中数据,核心是通过Iso7816Tag实例发送符合ISO7816标准的APDU指令:

  1. 转换标签实例:从识别到的NfcTag中提取Iso7816Tag对象,这是处理ISO7816指令的入口:

    final iso7816Tag = Iso7816Tag.from(tag);
    

    若转换失败,说明当前标签不支持ISO7816指令集。

  2. 构造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字节)
  3. 发送指令并处理响应:通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:45:36