Published by goodspeed on February 20, 2024
本来是打算读身份证的,但发现身份证的读取是专有且受限的。护照有国际统一的标准,所以我对护照下手。
护照(或者准确地说,电子护照:E-passport)中的芯片与常见的 M1 卡(一般门禁卡)不同。读取这样的卡片(即智能卡:Smartcard)一般通过 PCSC/CCID 协议与读卡器通讯,并且主要使用「智能卡应用协议数据单元」(ADPU)与智能卡进行通讯。
PN532 读卡器模块很便宜,但是要使用 PN532 必须通过 I2C/SPI/UART(HSU) 发送其用户手册规定的命令。市售的 PN532 模块一般工作在 HSU (High Speed UART) 模式下,并通过上面的 ch341 芯片转成 USB 接口。
所以,我们让 PN532 可以通过 PCSC 协议通讯。这里,需要用到 ifdnfc 程序。主流发行版已经打包 PCSC 库,但不幸的是,没有 ifdnfc,需要自行编译。
# apt install cardpeek
安装 PCSC:
# apt install pcscd pcsc-tools libpcsclite-dev
安装 libnfc:
# apt install libnfc-bin libnfc-dev
构建并安装 ifdnfc:
$ git clone --depth=1 https://github.com/nfc-tools/ifdnfc $ cd ifdnfc $ autoreconf -vis $ ./configure $ make && sudo make install
要让 pcscd 可以成功与 PN532,我们需要先找到 PN532 的位置。反复插拔 PN532 几次,然后查看 dmesg。你会看到类似下面的信息:
[ 8396.180095] usb 3-2: new full-speed USB device number 6 using xhci_hcd [ 8396.329106] usb 3-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64 [ 8396.329122] usb 3-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0 [ 8396.329126] usb 3-2: Product: USB Serial [ 8396.331080] ch341 3-2:1.0: ch341-uart converter detected [ 8396.332075] usb 3-2: ch341-uart converter now attached to ttyUSB0 [11469.467062] usb 3-2: USB disconnect, device number 6 [11469.467587] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0 [11469.467628] ch341 3-2:1.0: device disconnected
其中的 ttyUSBX 就是 PN532 串口设备的位置。随后我们配置 libnfc,在 /etc/nfc/libnfc.conf 中追加这两行:
device.name = "IFD-NFC" device.connstring = "pn532_uart:/dev/ttyUSBX"
然后可以试试 libnfc 能不能用。将随便一张 NFC 卡片置于 PN532 上,然后应该可以看到类似的内容:
# sudo nfc-list nfc-list uses libnfc 1.8.0 NFC device: IFD-NFC opened 1 ISO14443A passive target(s) found: ISO/IEC 14443A (106 kbps) target: ATQA (SENS_RES): 00 04 UID (NFCID1): 42 d3 f0 bc SAK (SEL_RES): 08
然后将 ifdnfc 配置为 PCSC 读卡器,创建 /etc/reader.conf.d/libifdnfc:
FRIENDLYNAME "IFD-NFC" LIBPATH /usr/local/lib/libifdnfc.so CHANNELID 1
启动 pcscd 与 ifdnfc
# service pcscd restart # ifdnfc-activate
=> 护照放置的照片
将护照背面的中心靠上位置贴于 PN532 上,然后运行命令:
$ pcsc_scan
你应该能找到你的护照(不知道为啥,它会觉得是 Spanish Passport)。
然后打开 cardpeek,选择名为 IFD-NFC 的读卡器。点击左上角的 Analyze 并选择 e-passport。
它会要求你输入 MRZ (Machine Readable Zone, 机器可读区域) 中的第二行,这是因为电子护照使用 BAC (Basic access control)。MRZ 在护照姓名页的最下面,第一行有一堆 <。
输入完 MRZ 的内容后稍等一会,cardpeek 就会读出护照上的内容。
读出来以后,可以看到 EF.DG1 中记录着 MRZ 的内容。MRZ 中记录着护照持有者的各种信息,具体解读方法见Wikipedia: 可机读护照。
和其它一堆二进制数据与无法读取的部分。
EF.SOD 也很有意思,记录着发照机构相关内容:
护照里面有头像和指纹,读指纹肯定没啥戏,但头像还是可以的。在 EF.DG2 可以看到 Image Data,将十六进制的字符串保存到文件,然后转换为二进制:
$ xxd -r -p data.hex data.bin
你可以发现它的确是图像文件:
$ file data.bin data.bin: JPEG 2000 codestream
这个格式稍微有点特殊,但使用 gimp 可以顺利打开。
text/gemini;lang=zh-CN
This content has been proxied by September (ba2dc).