Posted on

1. 背景知识

        Near-Field Communication(NFC)是一种近距离无线通信技术,又称近场通信。该技术使用13.56MHz的高频无线电在20厘米(实际工作距离10厘米)以内通信。由于其传输距离短无法被远距离读取,且通信过程不用产生物理接触,同时具有便捷性和安全性(注:此处安全指通信需要在较短距离内进行。不代表应用中存储的数据安全。如315晚会提到的QuickPass盗刷问题,QuickPass信息泄露问题等),因此被广泛应用于非接触式支付[1]。Visa的payWave、银联的QuickPass、苹果的Apple Pay、安卓手机的无线支付等均使用NFC技术[2]。一个完整的NFC设备有3种工作模式:卡模拟模式(Card emulation mode)、读卡器模式(Reader/Writer mode)、点对点模式(P2P mode)[3]。

图1. 英国公交站的NFC标签广告

        NFC除应用于支付领域外,由于其便捷的读取方式,被广泛制作为NFC电子标签,可以存储网址、邮箱、电话、电子名片等信息或自定义数据。NFC标签功能与二维码相似,但信息的读取不受环境光线影响,单位面积内信息量更大。其缺点为信息的读取需要硬件支持,且读取距离通常较二维码近。举一个直观的例子,下图为500字节信息的载体面积对比。

图2. QRCode与NFC TAG对比图

        部分手机内置NFC模块用于支付或信息读取。部分相机、耳机等内置NFC模块用户Wi-Fi、蓝牙等信息的传输。

图3. 索尼α7 II的NFC功能

        ACR122U是香港龙杰智能卡有限公司(Advanced Card Systems Ltd.)生产的NFC读卡器,使用PN532 NFC芯片,支持Mifare卡、ISO 14443 A类和B类卡、以及全部四种NFC标签。[4]由于其可以对Mifare等工作在13.56MHz的卡片进行研究或破解,也可以通过API对其进行二次开发,因此被安全研究人员广泛使用。

图4. ACR122U实拍

        NTAG215是荷兰的NXP(恩智浦)公司生产的NFC电子标签,采用ISO 14443A1-3标准,用户可以存储504比特数据,理论数据有效期10年。用户可以对其进行十万次的重复写入,并可以对其设置写入32位的密码,防止被恶意篡改。[5]

图5. 强光手电上的NTAG215

        本文讨论如果使用ACR122U和NTAG215以NFC Forum制定的NDEF格式标准读写存储网址、电子名片等内容的NFC TAG。[6]

2. 材料准备

  • ACR122U x1
  • PC x1
  • NTAG215(或其他型号的NTAG,区别如下)

图6. 各型号NTAG的区别[5]

3. 驱动安装

        通过ACS官网下载ACR122U驱动程序,官网驱动程序支持Windows、Mac、Linux的多个版本。 下载完成后运行安装即可。(MacOS安装驱动后重启生效,未在Linux平台进行测试。)

4. 信息写入与读取

        NTAG的读写可以通过支持NFC功能的安卓手机安装NXP官方的“NFC TagWriter by NXP”等APP直接进行读取。若通过PC操作,需使用ACR122U等NFC读卡器设备进行读写。

4.1 通过第三方软件

        互联网上可以查到大量的NFC读写工具,此处推荐使用wakdev.com的NFC TOOLS,该工具有Windows、Mac和Linux三个版本,并支持中英文等10国语言。下载地址:https://www.wakdev.com/apps/nfc-tools-pc-mac.html。

       安装完成后通过USB连接ACR122U读卡器,运行NFC Tools程序,在“Options”中可以看到已连接的设备。

图7. 读卡器的连接

        将NFC电子标签放置于读卡器中心区域,“Information”选项卡可以查看当前NFC  TAG中已存储的信息,“Memory”选项卡记录以往读取过的NFC标签中记录的信息。“Write”选项卡可以新建各种类型的数据并写入NFC标签。

图8. 新建记录

        新建完成后点击“Write”按钮写入数据。

图9. 数据写入成功

4.2 通过Python写入数据

        如果需要批量完成写入数据的操作,通过第三方软件很难实现。因此我们可以使用Python的第三方模块nfcpy进行操作,该模块支持Windows和Linux系统。以Windows系统为例,首先使用pip install nfcpy模块,以及该模块所依赖的Wi nUSB,libusb(此处可以使用USB驱动集成软件Zadig安装)[7]。

        通过python -m nfc命令即可查找已经连接的NFC Reader,若未连接成功会得到正确连接的建议。

通过以下代码可以连接NFC设备(来自nfcpy官方文档[8]):

>>> import nfc

>>> clf = nfc.ContactlessFrontend(‘usb’)

通过以下代码可以读取NFC标签的内容:

>>> tag = clf.connect(rdwr={‘on-connect’: lambda tag: False})

>>> print(tag)

Type3Tag ‘FeliCa Standard (RC-S960)’ ID=01010701260CCA02 PMM=0F0D23042F7783FF SYS=12FC

 NDEF是由NFC Forum制定的NFC标签数据格式标准,使用ndef模块可以对其进行编码解码操作。通过对tag.ndef.records实例的读取或赋值,可以直接操作NFC标签中数据,一个NFC标签中可以存储多个不同类型的数据。读取数据代码如下: 

>>> record = tag.ndef.records[0]

>>> print(record.type)

urn:nfc:wkt:U

>>> print(record.uri)

http://nfcpy.org

写入数据代码如下:

>>> import ndef

>>> uri, title = ‘http://nfcpy.org’, ‘nfcpy project’

>>> tag.ndef.records = [ndef.SmartposterRecord(uri, title)]

操作完成后最终关闭连接:

>>> clf.close()

5. 总结

虽然NFC电子标签较二维码存在诸多优势,目前大部分安卓手机已经支持全模式NFC功能,但是由于庞大的苹果用户群体存在(iPhone X及更新型号已支持无需第三方APP直接读取NDEF格式的URL),NFC标签仍无法普及。但是我仍然期待一个场景,N年以后,两个人见面交换名片或者互加好友的时候,只需要轻轻靠近对方的手机或者工牌就可以完成。

参考资料:

  1. https://en.wikipedia.org/wiki/Near-field_communication
  2. https://en.wikipedia.org/wiki/Contactless_payment
  3. https://www.iso.org/standard/38578.html
  4. https://www.acs.com.hk/en/products/3/acr122u-usb-nfc-reader/
  5. https://www.nxp.com/products/secure-identification/smart-label-and-tag-ics/ntag/ntag-for-tags-labels:NTAG-TAGS-AND-LABELS#/
  6. https://nfc-forum.org
  7. https://zadig.akeo.ie
  8. https://nfcpy.readthedocs.io/en/latest/topics/get-started.html

注:本文为原创文章,部分引用已注明,见参考资料。转载请注明来自li-yang.cn。