NFC读取器“SELECT(通过AID)” APDU未路由到Android设备 [英] NFC reader "SELECT (by AID)" APDU is not routed to Android device

查看:684
本文介绍了NFC读取器“SELECT(通过AID)” APDU未路由到Android设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的ACR122U NFC读写器连接到安装了ACR122驱动程序的Windows机器。

I have an ACR122U NFC reader/writer connected to my Windows machine with ACR122 driver installed.

我尝试使用 javax.smartcardio API将SELECT(由AID)ADPU发送到我的Android设备(应该处于HCE模式)。

I try to use javax.smartcardio API to send an SELECT (by AID) ADPU to my Android device (which should be in HCE mode).

这是我的代码:

TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
CardTerminal terminal = terminals.get(0);
System.out.println(terminal.getName());
Card card = terminal.connect("*");
CardChannel channel = card.getBasicChannel();
execute(channel, new byte[] { (byte) 0xFF, 0x00, 0x51, (byte) 195, 0x00}, card);
execute(channel, new byte[] { (byte)0xFF, 0x00, 0x00, 0x00, 0x04,(byte)0xD4, 0x4A, 0x01, 0x00}, card); //InListPassiveTarget
execute(channel, new byte[] { (byte)0xFF, 0x00, 0x00, 0x00, 0x04,(byte)0xD4, 0x4A, 0x01, 0x00}, card); //InListPassiveTarget
execute(channel, new byte[] {0x00, (byte) 0xA4, 0x04, 0x00, 7,
                (byte)0xF0, 0x01, 0x02, 0x03, 0x04, (byte) 0x05, 0x07, 0}, card); //select AID

...

public static void execute(CardChannel channel, byte[] command, Card...cards) throws CardException {
    ByteBuffer r = ByteBuffer.allocate(1024);
    channel.transmit(bufferFromArray(command), r);
    System.out.println(convertBinToASCII(r.array(), 0, r.position()));
}

这是我得到的输出:


ACS ACR122 0
3B8F8001804F0CA000000306030000000000006B
C3
D54B6300
D54B010108032004010203049000

我猜 01020304 是我的Android设备向NFC阅读器提供的UID。 SELECT APDU没有响应,它的长度为0个字节。

I guess 01020304 is the UID presented by my Android device to the NFC reader. The SELECT APDU returns no response, it's 0 bytes long.

在我的Android设备上,我有这项服务:

On my Android device I have this service:

public class MyHostApduService extends HostApduService {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("APDU", "APDU service was created.");
    }

    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
       Log.e("APDU", "command apdu: " + Arrays.toString(apdu));
       return new byte[2];
    }
    @Override
    public void onDeactivated(int reason) {
       Log.e("APDU", "ON DEACTIVATED.");
    }
}

但是 processCommandAdpu 没有被调用。查看日志时,我发现SELECT ADPU被发送到读卡器时无法找到任何内容,因此似乎ADPU甚至没有进入Android设备。

But processCommandAdpu is not getting called. Looking through the logs I wasn't able to find anything when the SELECT ADPU is supposedly sent to the reader, so it seems like the ADPU doesn't even get to the Android device.

这是Android项目的apduservice.xml:

This is the apduservice.xml for the Android project:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/servicedesc"
    android:requireDeviceUnlock="false" >
    <aid-group
        android:category="other"
        android:description="@string/aiddescription" >
        <aid-filter android:name="F0010203040507" />
    </aid-group>
</host-apdu-service>

此外,有几个ADPU在传输时会使NFC读卡器卡住。例如,

Besides there are several ADPUs which when transmitted make the NFC reader somewhat stuck. For example,

execute(channel, new byte[] {(byte) 0xFF, 0x00, 0x00, 0x00, 0x02, (byte) 0xd4, 0x04}, card);

这是一个查询PN532芯片当前状态的伪APDU,不会返回任何响应。难道这个特定的读者有缺陷吗?我怎么检查呢?

which is a pseudo APDU to query current status of PN532 chip does not return any response. Can it be that this particular reader is flawed? How can I check it?

UPDATE (基于讨论聊天):

使用第二个读者进行测试(同样的型号,相同的版本)刚刚起作用。所以它可能是第一个阅读器上的一些模糊设置或者阅读器出现故障。

A test with a second reader (same model, same version) just worked. So it might either be some obscure settings on the first reader or the reader was just malfunctioning.

两个阅读器都有相同的版本信息:

Both readers have the same version information:


  • ACR122U固件版本:41435231323255323135( - > ACR122U215)

  • PN532版本:D503 32010607 9000( - > PN532 v1.6)

推荐答案

您使用InListPassiveTarget直接指示ACR122U内的PN532 NFC芯片手动轮询标签。这基本上绕过了ACR122U的抽象层,允许您自动轮询标签并使用标准PC / SC与枚举的智能卡交换APDU命令。因此,通过PC / SC接口发送普通APDU将无法工作,SELECT APDU将永远不会到达Android HCE端。

You used InListPassiveTarget to directly instruct the PN532 NFC chip inside the ACR122U to manually poll for tags. This essentially bypasses the abstraction layers of the ACR122U that allow you to automatically poll for tags and use "standard PC/SC" to exchange APDU commands with the enumerated smartcard. Consequently, sending plain APDUs over the PC/SC interface won't work and the SELECT APDU will never arrive at the Android HCE side.

相反,您还需要通过直接与PN532传输模块通信来交换APDU命令。您可以通过在InDataExchange命令中包装APDU命令来实现此目的(如果您需要控制ISO / IEC 14443-4标头字段,则可以使用InCommunicateThru)。在您的情况下,包装的SELECT(通过AID)命令APDU将类似于:

Instead, you will also need to exchange APDU commands by speaking directly with the PN532 transmission module. You can do this by wrapping your APDU command inside an InDataExchange command (or InCommunicateThru if you need control over ISO/IEC 14443-4 header fields). In your case, the wrapped SELECT (by AID) command APDU would look something like:

execute(channel, new byte[] {
    (byte)0xFF, 0x00, 0x00, 0x00,  // direct PN532 command
    16,                // Lc = command length
    (byte)0xD4, 0x40,  // InDataExchange
    0x01,              // Tag #1 (equal to the tag number from the InListPassiveTarget response)
    0x00, (byte)0xA4, 0x04, 0x00,                         // APDU: SELECT (by AID)
          7,                                              // Lc = AID length
          (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, // AID = F0010203040507
          0x00,                                           // Le = max
}, card);



这个特定的读者是否存在缺陷?



是的,虽然我对此表示怀疑,但情况可能就是这样。请注意,ACR122U固件有许多不同版本,其中大多数似乎都存在设计缺陷。特别是某些版本的阅读器执行自动标签枚举而有些版本没有,并且可用的API在该阅读器的不同版本中发生了巨大变化,因此很难为该设备进行编程。

Can it be that this particular reader is flawed?

Yes, this could be the case though I rather doubt that. Note that there are many different versions of the ACR122U firmware and most of them seem to be flawed by design. Particularly the fact that some versions of the reader perform automatic tag enumeration and some don't, and that the available API changed drastically across different versions of that reader make it difficult to program for that device.


  • 对InListPassiveTarget命令的响应不包含ATS数据(在UID字段之后)。也许您的读者在标签选择期间不执行自动RATS。这可以使用SetParameters命令(在InListPassiveTarget之前)启用:

  • The response to the InListPassiveTarget command does not contain ATS data (after the UID field). Maybe your reader does not perform automatic RATS during tag selection. This can be enabled using the SetParameters command (before InListPassiveTarget):

execute(channel, new byte[] {
    (byte)0xFF, 0x00, 0x00, 0x00,  // direct PN532 command
    3,                 // Lc = command length
    (byte)0xD4, 0x12,  // InDataExchange
    (1<<4),            // fAutomaticRATS = 1
}, card);

您还可以尝试使用InCommunicateThru手动发送RATS命令:

You could also try to manually send a RATS command using InCommunicateThru:

execute(channel, new byte[] {
    (byte)0xFF, 0x00, 0x00, 0x00,  // direct PN532 command
    4,                 // Lc = command length
    (byte)0xD4, 0x42,  // InCommunicateThru
    (byte)0xE0, 0x80,  // RATS (FSD = 256, CID = 0)
}, card);

之后,您可以尝试使用InCommunicateThru和原始ISO / IEC 14443-4块与卡通信:

After that you could try to communicate with the card using InCommunicateThru and raw ISO/IEC 14443-4 blocks:

execute(channel, new byte[] {
    (byte)0xFF, 0x00, 0x00, 0x00,  // direct PN532 command
    16,                // Lc = command length
    (byte)0xD4, 0x42,  // InCommunicateThru
    0x02,              // PCB (I-block, change to 0x03 for the next block)
    0x00, (byte)0xA4, 0x04, 0x00,                     // APDU: SELECT (by AID)
      7,                                              // Lc = AID length
      (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, // AID = F0010203040507
      0x00,                                           // Le = max
}, card);


  • ATQA 0803 看起来很奇怪。特别是位帧防冲突字段中的0x03表明该字段中存在多个目标(因为符合标准的标记仅在位帧防冲突字段中设置单个位)。 请注意,不是真的。响应InListPassiveTarget的ATQA是以little endian传输的。因此,位帧防冲突值为0x08(=有效/兼容),专有字段中的值为0x03。

  • The ATQA 0803 looks rather odd. Especially the 0x03 in the bit frame anticollision field suggests that there is more than one target in the field (since a standards compliant tag would only set a single bit in the bit frame anticollision field). Note that this is not true. The ATQA in the response to InListPassiveTarget is transmitted little endian. Consequently, the bit frame anticollision value is 0x08 (= valid/compliant) and the value in the proprietary field is 0x03.

    确实如此,奇怪的是你的读者没有回应某些PN532命令(特别是因为固件版本 32010607 看起来很好)。我用另一个ACR122U测试了一些失败的命令,并且它们成功完成了......

    It's, indeed, strange that your reader does not respond to certain PN532 commands (particularly since the firmware version 32010607 looks fine). I've tested some of the commands that fail for you with another ACR122U and they completed successfully ...

    这篇关于NFC读取器“SELECT(通过AID)” APDU未路由到Android设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆