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

如何正确读取MIFARE DESFire EV2卡中0x01与0x02文件的数据?

解决MIFARE DESFire EV2读取文件返回91 9D错误的问题

错误原因分析

返回的91 9D是DESFire的参数无效错误码,问题出在读取文件的指令参数设置上:

  • 你将读取长度设为00 00 00,这不符合DESFire EV2的指令规范,该值无法触发“读取全部文件数据”的逻辑,反而会被判定为无效参数。
  • 未校验选应用指令的执行结果,若选应用失败(比如卡未正确响应),后续读文件指令必然报错。

修正后的代码实现

const readNfc = async () => {
  if (isReadingNfc) {
    return;
  }
  setIsReadingNfc(true);
  let response = null;
  try {
    // 优先使用IsoDep技术,更适配DESFire的ISO7816-4指令交互
    await NfcManager.requestTechnology(NfcTech.IsoDep);
    console.warn("1: 已获取NFC技术支持");

    // 定义工具函数:校验指令响应状态码
    const checkResponse = (res) => {
      const status1 = res[res.length - 2];
      const status2 = res[res.length - 1];
      if (status1 !== 0x90 || status2 !== 0x00) {
        throw new Error(`指令执行失败,状态码: 0x${status1.toString(16)} 0x${status2.toString(16)}`);
      }
      return res.slice(0, res.length - 2); // 返回有效数据(剔除状态码)
    };

    // 选择0xFFFFFF应用
    const selectRes = await NfcManager.transceive([
      0x90, 0x5a, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00,
    ]);
    checkResponse(selectRes);
    console.warn("2: 已选中目标应用");

    // 读取文件0x01:指定偏移0,读取长度设为0x0000FF(255字节,覆盖大部分文件长度)
    const fileX01Res = await NfcManager.transceive([
      0x90, 0xbd, 0x00, 0x00, 0x07, 
      0x01, // 文件号
      0x00, 0x00, 0x00, // 偏移量(从文件开头读)
      0x00, 0x00, 0xff, // 读取长度(255字节,可根据实际文件长度调整)
      0x00 // Le:允许卡返回所有请求的数据
    ]);
    const data1 = checkResponse(fileX01Res).toString("ascii");
    console.warn("3: 文件0x01数据", data1);

    // 读取文件0x02:同上述参数逻辑
    const fileX02Res = await NfcManager.transceive([
      0x90, 0xbd, 0x00, 0x00, 0x07, 
      0x02, // 文件号
      0x00, 0x00, 0x00, // 偏移量
      0x00, 0x00, 0xff, // 读取长度
      0x00
    ]);
    const data2 = checkResponse(fileX02Res).toString("ascii");
    console.warn("4: 文件0x02数据", data2);

    response = { data1, data2 };
    console.warn("5: 读取完成", response);
    setNfcTagData(response);
  } catch (error) {
    console.error("NFC读取错误:", error);
    setNfcError(error);
  } finally {
    await NfcManager.cancelTechnologyRequest();
    setIsReadingNfc(false);
  }
  return response;
};

关键修改点说明

  • 添加状态码校验:每次transceive后检查响应末尾的90 00状态码,确保前序指令执行成功再继续。
  • 修正读取长度参数:将读取长度从00 00 00改为00 00 FF,该值表示读取255字节数据(若文件长度小于255,卡会自动返回实际长度的数据)。
  • 优先使用IsoDep技术:虽然你测试NfcA也能触发交互,但IsoDep是专门针对ISO7816-4协议的NFC技术,更适配DESFire卡的指令交互逻辑。

内容的提问来源于stack exchange,提问作者Pepito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:38:23