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

为ISO 14443 NFC标签设置密码保护遇问题求助

搞定FM11NT021 NFC标签密码设置的坑

先理清楚FM11NT021的密码逻辑

FM11NT021是ISO14443A协议的标签,密码保护涉及三个关键配置:

  • PWD(密码):固定4字节,存储在地址0x2C-0x2F
  • PACK(密码验证响应):固定2字节,存储在地址0x30-0x31
  • AUTH0:1字节,存储在地址0x2B,用来定义「从哪个地址开始需要密码验证」——比如你存128字节NDEF的区域是0x00-0x7F,把AUTH0设为0x80,就只有配置区(0x28及以后)需要验证,不会影响NDEF的正常读写;要是设成0x00,全区域都要密码,包括写AUTH0本身,很容易触发死循环。

你遇到的两个核心问题:

  1. 写入PWD、PACK后再写AUTH0时出现「连接丢失」
  2. 调用writeNdefWithPass或authenticatePassword返回的PACK为[0,0]

一步步排查修正

1. 先确认命令和地址有没有写错

FM11NT021的配置区不能用NDEF写入命令操作,必须用块写入命令(0xA2)。很多人踩坑就是误用了NDEF的写入方法,直接导致报错。

给你一个正确的配置区写入代码示例:

async function setTagPassword(passwordBytes, packBytes, auth0Value) {
  try {
    // 先校验参数长度:密码必须4字节,PACK必须2字节
    if (passwordBytes.length !== 4 || packBytes.length !== 2) {
      throw new Error('密码需为4字节,PACK需为2字节');
    }

    // 1. 写入密码:块地址0x0B(对应字节0x2C-0x2F)
    await NfcManager.transceive([0xA2, 0x0B, ...passwordBytes]);
    
    // 2. 写入PACK:块地址0x0C(对应字节0x30-0x33),不能覆盖后2字节的其他配置位
    const originalPackBlock = await NfcManager.transceive([0x30, 0x0C]); // 先读取原有块内容
    const newPackBlock = [...packBytes, originalPackBlock[2], originalPackBlock[3]]; // 替换前2字节为目标PACK
    await NfcManager.transceive([0xA2, 0x0C, ...newPackBlock]);
    
    // 3. 写入AUTH0:块地址0x0A(对应字节0x28-0x2B),替换第4字节(索引3)为目标AUTH0值
    const originalAuth0Block = await NfcManager.transceive([0x30, 0x0A]);
    const newAuth0Block = [originalAuth0Block[0], originalAuth0Block[1], originalAuth0Block[2], auth0Value];
    await NfcManager.transceive([0xA2, 0x0A, ...newAuth0Block]);
    
    return true;
  } catch (err) {
    console.error('设置密码失败:', err);
    return false;
  }
}

2. 解决「连接丢失」问题

  • 操作顺序不能乱:必须严格遵循「写PWD→写PACK→写AUTH0」的顺序。要是先写AUTH0,一旦AUTH0生效,后续写PWD/PACK就需要密码验证,直接卡壳。另外AUTH0的值别设太小,参考前面的建议,避开NDEF存储区,避免写AUTH0时触发密码验证。
  • 控制命令间隔:Android平台NFC标签的连接超时很短,连续的transceive命令要尽量快速执行,别加不必要的延迟。实在需要等待,加100ms以内的小延迟即可:await new Promise(resolve => setTimeout(resolve, 100))。
  • 排查标签供电:部分廉价标签连续写入时会出现供电不足,导致断连。可以分步测试,每写完一步就读取配置区确认,再执行下一步。

3. 解决PACK返回[0,0]问题

  • PACK写入地址错误:FM11NT021的PACK在0x30-0x31,属于块0x0C的前2字节,不能直接覆盖整个块,必须保留后2字节的其他配置位(比如锁定位)。上面的代码已经处理了这个问题,写完后可以用读命令确认0x30-0x31的值是否为你设置的PACK。
  • 认证前未激活标签:调用authenticatePassword前,必须确保标签处于激活状态,先执行await NfcManager.requestTechnology(NfcTech.IsoDep)或NfcTech.Ndef,否则标签无响应,会返回默认的[0,0]。
  • 密码参数错误:如果传入的密码不是4字节的数组/Uint8Array,或者密码值错误,标签也会返回[0,0]。先确认密码参数的格式和长度正确。

4. 平台权限与兼容性注意

  • Android:清单文件中必须添加<uses-permission android:name="android.permission.NFC" />,还要添加TECH_DISCOVERED过滤,指定支持ISO14443A和FM11NT021的技术类型。
  • iOS:iOS对NFC低级命令限制较多,react-native-nfc-manager可能无法直接操作标签配置区,需要用原生CoreNFC写扩展,或者换用iOS支持的标签操作方法。

测试小技巧

  1. 先用NFC Tools这类第三方APP手动设置密码、PACK、AUTH0,确认标签本身功能正常。
  2. 分步测试代码:先只写PWD,读配置区确认写入成功;再写PACK,读确认;最后写AUTH0。
  3. 开启调试日志:NfcManager.setLogLevel('debug'),查看底层发送的命令和标签响应,快速定位问题点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:35:24