繁体   English   中英

通过javax.smartcardio阅读幻像NFC标签

[英]Reading phantom NFC tags via javax.smartcardio

我有一个旧的NFC阅读器用于tikitag web服务(后来改名为touchatag ,最后在2012年左右放弃)。 由于网站不再可用,我再也找不到原始的tikitag / touchatag驱动程序了。 经过一番搜索,我发现这款NFC读卡器是一款通用的ACS ACR122U USB读卡器,并从这里安装了合适的驱动器。 我的系统是Windows 7(64位)。

首先,我尝试使用NFC Tools库对NFC标签进行高级读写访问。 我收到一个错误,说遇到了不支持的标签; 虽然阅读器上没有标签,甚至附近也没有标签。 看来,其他开发商也与此库遇到了同样的错误,如图所示这里 请注意,此标记无限期地被检测到(因此,它不会在被检测到一次后消失)。

我将所需的低级代码复制到一个单独的类中(即独立于NFC工具库)。 您可以在下面找到此代码(类似的代码也可以在教程中找到):

import java.util.List;

import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;

import org.nfctools.utils.NfcUtils;

public class NdefTest {

    public static void main(String[] args) throws Exception {
        TerminalFactory factory = TerminalFactory.getDefault();
        List<CardTerminal> terminals = factory.terminals().list();
        CardTerminal terminal = terminals.get(0);

        if (terminal.waitForCardPresent(5000)) {
            Card card = terminal.connect("T=0");
            System.out.println(NfcUtils.convertBinToASCII(card.getATR().getHistoricalBytes()));
        }
    }
}

此代码检测与使用NFC工具库时完全相同的“幻像”标记。 因此,这个问题似乎与NFC工具库无关(正如图书馆开发人员在回复错误报告时所暗示的那样)。 要么我遗漏了某些东西,要么问题与安装的驱动程序,NFC读卡器硬件或javax.smartcardio中的某些未修复的错误有关(按可能性顺序列出)。

我已经尝试卸载上述驱动程序并让Windows 7自行安装合适的驱动程序(称为“Microsoft Usbccid智能卡读卡器(WUDF)”),这会导致与上述相同的错误。 我没有尝试过另一个读者,因为我只有一个。

(注意:Windows设备概述中此NFC阅读器的名称是“CCID USB Reader”,而不是“ACS ACR122”或相关的东西。不知道这是否重要,只是想我会提到它。)。

有没有人遇到过这个问题,并设法解决了吗?

UPDATE

好的,我已经尝试在检测到模拟标签后向阅读器发送CLF命令; 即,获取连接的PICC的ATS( ACR122U手册第11页):

TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();

// (this is the correct terminal)
CardTerminal terminal = terminals.get(0);

if (terminal.waitForCardPresent(5000)) {
    Card card = terminal.connect("*");

    CardChannel channel = card.getBasicChannel();

// (I tried both 0x00 and 0x01 as P1, as well as 0x05 for Le)
    CommandAPDU getAts = new CommandAPDU(0xFF, 0xCA, 0x00, 0x00, 0x04);
    ResponseAPDU response = channel.transmit(getAts);

    System.out.println(response.getSW1());
    System.out.println(response.getSW2());
}

但我一直收到错误响应代码(0x63 0x00)。 关于我可能做错的任何想法?

您遇到的问题是此版本的ACR122U阅读器以某种非标准方式使用PC / SC(CCID)。

使用PC / SC API检测到的“卡”实际上是读卡器模拟的虚拟卡(即使没有卡也允许PC / SC API打开连接)或读卡器SAM中的智能卡芯片插槽(读卡器外壳内有接触卡)。

在任何一种情况下,该阅读器仅将PC / SC用作该阅读器(NXP PN532)中使用的非接触式前端芯片的本机命令的传输协议。 因此,如果要使用阅读器的非接触式功能,则必须使用CLF的本机命令集。 有关更多详细信息,请参阅ACR122U API文档libnfc实现。

(所有功劳都归功于Michael Roland;这篇文章的意思是解决方案摘要)

好的迈克尔,考虑到你上次评论中的例子,我终于理解了使用PC / SC协议来隧道化CLF命令的意思。 我测试了PN532文档中的一些命令,它们返回了有效的结果。 (但是,您作为示例提供的命令不起作用并使读取器崩溃;必须重置它。)

例如,要获取固件版本:

CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x02 });

InDataExchange命令:

CommandAPDU commApdu = new CommandAPDU(0xFF, 0x00, 0x00, 0x00, 
    new byte[] { (byte)0xD4, (byte)0x40, 0x01 });

我找到了NFCIP库 ,它支持使用InDataExchange命令在对等体之间发送字节数组(例如ACS ACR122和Nokia 6131)。 阅读PN532文档(p.131)时,似乎此命令也允许读取标签。 迈克尔,你碰巧知道任何处理的库使用这些低级命令,目的是阅读(不同类型的)标签吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM