我桌上放着一枚 ICODE 3 标签,iPhone 压在它上面,App 正顺顺当当地读出芯片知道的一切:它的 ID、内存、轻触计数,还有证明它是原装货的 NXP 签名。接着我让 App 改一样东西,就改那个计数器,它却告诉我标签已经移开了。
标签根本没动。我又试了一次,还是那条提示。我改成设置密码,依然是那条提示。
到底怎么回事,我稍后再讲,因为这是我今年追过的最有意思的一个 bug。不过先说说,我为什么会去折腾一枚 ICODE 标签。
我希望 NFC.cool 成为你手机上能装的最强大的 NFC App。今年夏天,我为此补上了 NTAG 424 DNA,也就是品牌用来证明产品是正品的那种标签。做完之后,App 还没法真正对上话的最大一个芯片家族,就剩 NXP 的 ICODE 了。从 NFC.cool Tools 7.1.0 开始,App 也能和它对话了。
ICODE:你早就摸过、却从没留意的标签
如果你在过去二十年里从图书馆借过书,那你很可能已经摸过 ICODE 标签了。就是贴在封面内侧、带着一圈盘绕天线的那张扁平标签。同样的芯片也藏在商店的防盗标签、洗衣标签和商品标签里。
从技术上讲,它们是 ISO 15693 芯片,在 NFC 的体系里叫 Type 5。大多数人买的 NFC 贴纸,比如 NTAG215,用的是另一套标准。我常把它们想成同一条街上的两家店:iPhone 两家都进得去,可进了门才发现,两家说的是不同的方言。
图书馆和商店选 ICODE,看中的是读取距离。图书馆门口的检测门或者自助借还机上那种大天线,能在比普通 NFC 贴纸更远的地方读到这些芯片。用手机读的时候,你还是得贴得很近,因为 iPhone 的天线很小,可这种芯片本来就是为那些检测门设计的。
读出 ICODE 标签里存的链接或文本,从来都不是难事。真正有意思的东西藏在下面一层:密码、计数器、防盗标志、隐私模式。芯片的这一层,NFC.cool 以前一直碰不到,现在终于能了。
NFC.cool 能拿 ICODE 3 做什么
ICODE 3 是 NXP 这个家族里最新的芯片,也是 ICODE SLIX2 的继任者。网上常有人把它当成“SLIX 3”来卖。NXP 并没有叫这个名字的芯片,所以如果商品页上写着 SLIX 3,那其实就是 ICODE 3。
用 NFC.cool 轻触一枚,你就能看到全貌:它是哪款芯片、内存多大、计数器读数多少,以及它是不是原装 NXP 芯片。NXP 在出厂时会给每枚芯片的 ID 签名,App 会核验这个签名,所以就算仿品照抄了 ID,这个签名它也伪造不了。
在此基础上,芯片提供的几乎所有设置你都能改:
轻触计数器。ICODE 3 能自己统计每一次读取。打开 NFC 镜像后,芯片会把自己的 ID 和当前计数写进存储的链接里,于是每次轻触打开的都是一个略有不同的 URL,网站可以据此计数。如果你读过 NFC 轻触计数器那篇,这就是同一个思路,只是换了一种芯片。
密码。ICODE 3 有六个密码,分别管读取、写入、隐私、销毁、防盗设置和配置。每枚标签出厂时的密码都一样,所以只有换上你自己的密码,保护才真正有意义。NFC.cool 会按标签把密码分别存进你的 iCloud 钥匙串。
内存保护。你可以把内存分成两部分,各自单独保护,比如让公开的链接谁都能读,同时把存在它后面的数据藏起来。
防盗和图书馆设置。EAS 标志决定了商店或图书馆门口的检测门会不会响。AFI 字节则是图书馆用来标记一本书已借出的。这两项都能修改,也都能锁定。
隐私模式。标签会把自己的 ID 和数据藏起来,直到有人出示隐私密码。
防拆检测。适用于 SL2S3003TT 版本,它带一根导线,可以绕过瓶盖,或者横跨盒子的封口。App 会显示这道封口是否曾被破坏。
自己的签名。品牌可以用自己的签名替换 NXP 的签名,并把它锁定。
销毁。永久关闭芯片,在产品生命周期结束时保护隐私。
其中好几项设置是永久性的,还有几项会让标签从此没法再被 iPhone 读到。所以凡是无法撤销的操作,NFC.cool 都会先让你输入标签 ID 的最后四个字符。它也不会去改动你一开始操作的那枚之外的任何标签。就算这样,凡是没试过的操作,我还是会先拿一枚备用标签练手。
还有一个顺手修好的小问题:现在你可以直接在 App 里把空白的 ICODE 标签格式化成 NFC 标签,之后就能往里写链接或文本了。
ICODE 家族的其他芯片
App 会识别出你手里拿的是哪款芯片,并且只提供这款芯片真正支持的功能。老款 SLIX 能看到的选项比 ICODE 3 少,原因很简单,芯片本身的功能就少。
SLIX、SLIX-S、SLIX-L、SLIX2 以及更老的 SLI 芯片,是大多数图书馆里挑大梁的主力。SLIX2 有计数器和内存保护。SLIX-S 按页保护内存,支持 64 位密码,这种模式下每次受保护的访问都要同时提供读取密码和写入密码。
ICODE DNA 是家族里主打安全的那一款。它内部存有永远不会离开芯片的 AES 密钥。在 NFC.cool 里输入密钥,App 就会向芯片发起挑战,让它证明自己确实持有这把密钥。就算一枚仿品的 ID 和内存都一模一样,也过不了这一关。
NTAG 5 是最让我这个爱折腾的人兴奋的一款。它是专门装在电路板上用的 NFC 芯片。switch 型号直接驱动引脚,link 和 boost 型号则通过 I2C 与微控制器通信。它们能单靠手机的射频场给一个小电路供电,在引脚上发出事件信号,还能和电路板共享 256 字节的内存。NFC.cool 能读取并修改这些设置,在 NTP5332 和 NTA5332 上,你甚至能直接用 iPhone 和接在芯片上的传感器通信。
这些功能都在 NFC 工具里的 NXP ICODE 和 NTAG 5 下面,就在 NTAG 424 DNA 旁边。或者直接扫描一枚 ICODE 标签,App 会自动打开它的详情。
一个 iOS 不让我修的 bug
再说回我桌上那枚“已经移开”的标签。
ISO 15693 给了手机两种和标签对话的方式。一种是在每条消息上都写明标签的 ID,就像在信封上写收件人的名字,这样只有那枚标签会应答。另一种是先选中这枚标签,就像在一屋子人里转身面向其中一位,之后直接开口就行。
写信封的办法更干净利落,所以 NFC.cool 会先试它。为了确认这条路走得通,App 发出一条带 ID 的简短测试消息。标签回应了,于是 App 得出结论:带地址的消息没问题,然后就继续往下走了。
问题出在一件我当时不知道的事上。iOS 把这些命令分成了两组:一组是每枚 ISO 15693 芯片都懂的标准命令,另一组是 NXP 自家的命令,也就是管密码、计数器和配置的那些。当一条带地址的消息里装的是 NXP 自家的命令时,iOS 会拒绝发送,这条消息压根出不了手机。iOS 只是悄悄返回一个“invalid parameter”(参数无效)错误,而在我的代码看来,这个错误和标签滑走了一模一样。
我的测试消息用的是标准命令,所以一路畅通无阻,告诉我一切正常。可每一次真正的修改用的都是 NXP 命令,所以每一次都失败了。
一旦想明白,修起来简单得都有点不好意思。现在的测试改用 NXP 自家的一条命令,这条命令完全无害,只是向芯片要一个随机数。如果 iOS 拒绝发送,App 就改用先选中标签的方式。我把 ICODE 3 放回 iPhone 下面,点了设置计数器,标签上的数字变了。我很少因为一个计数器跳了一下就这么高兴。
在哪些设备上能用
在 iPhone 上,这一切都靠手机内置的 NFC 读取模块完成。iPad 和 Mac 没有 NFC 芯片,要通过外置 USB NFC 读卡器来用。读卡器必须能把 ICODE 命令原封不动地转发给标签。如果你的读卡器可以,App 读取和管理 ICODE 标签的方式就和在 iPhone 上完全一样,而且上一节那个 bug 在那里根本不存在。不支持转发的读卡器,也依然能让你读取标签的内存。
Android 版 App 目前还不支持 ICODE。
如果你抽屉里攒着一堆图书馆那种标签,一直没派上什么用场,或者有块 NTAG 5 电路板正等着一个项目,那就更新到 7.1.0,轻触一枚试试。NFC.cool Tools 可以在 App Store 下载。