如何为阅读器获取AID基于主机的卡仿真

时间:2015-01-10 14:39:32

标签: android nfc rfid apdu hce

我正在尝试使用 ACR1281U NFC标签阅读器使用此Host card emulation在Android设备上进行example

This是我想要的那种应用程序。

根据Android文档和示例,需要在Android项目中注册AID:

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

我如何在Android应用程序中知道我需要注册哪个AID ,以便读者可以阅读HCE Android应用程序?

以下是我发布的另一个问题:No supported card terminal found ARC1281U nfc card reader

我已经提到了以下链接,但没有多大帮助:

请帮助,因为HCE上的资源非常少!

修改

该示例在SELECT(通过AID)命令中使用AID F0010203040506,但我的ACR128阅读器无法读取HCE设备。

private static final byte[] CLA_INS_P1_P2 = { 0x00, (byte)0xA4, 0x04, 0x00 };
private static final byte[] AID_ANDROID = { (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

private byte[] createSelectAidApdu(byte[] aid) {
    byte[] result = new byte[6 + aid.length];
    System.arraycopy(CLA_INS_P1_P2, 0, result, 0, CLA_INS_P1_P2.length);
    result[4] = (byte)aid.length;
    System.arraycopy(aid, 0, result, 5, aid.length);
    result[result.length - 1] = 0;
    return result;
}

然后我将AID更改为F00000000A0101(其他一些示例应用程序使用)并在AID过滤器中使用它。更改为此AID后,ACR阅读器能够检测到HCE设备。

  • 两个AID(example中使用的AID不起作用,另一个app中使用的AID)符合规范,如何知道要使用哪个AID?
  • 该示例在AID过滤器中添加多个AID,但在SELECT(通过AID)APDU中仅发送其中一个AID。我还应该在AID过滤器中添加多个AID吗?有什么用?

1 个答案:

答案 0 :(得分:19)

AID是&#34;名称&#34;您分配给智能卡应用程序(在HCE的情况下:模拟卡应用程序的Android应用程序)。读者应用程序使用这个&#34; name&#34;使用SELECT(通过DF名称/ AID)APDU命令寻址您的卡(HCE)应用程序(参见ISO / IEC 7816-4)。您可以使用任何您想要的值,只要它符合ISO / IEC 7816-4。

在您的具体情况下,reader example application使用AID F0010203040506

private static final byte[] AID_ANDROID = { (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

因此,要与该示例互操作,您需要为AID F0010203040506注册您的HCE服务。

如何分配和使用AID?

通常,您首先定义一个&#34;名称&#34;为您的HCE应用程序:

<host-apdu-service ...>
    <aid-group ...>
        <aid-filter android:name="F0010203040506"/>
    </aid-group>
</host-apdu-service>

稍后,读者应用程序可以使用该名称来选择您的HCE应用程序,然后与之通信(使用Java,例如使用Java智能卡IO):

Card card = ...;
CardChannel c = card.getBasicChannel();

// SELECT by AID (F0010203040506)
ResponseAPDU  resp = c.transmit(new CommandAPDU(
        0x00, 0xA4, 0x04, 0x00, new byte[] { (byte)0xF0, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06 }));
assert resp.getSW() == 0x9000;

// Send application-specific command (what such a command could look like depends on your application)
resp = c.transmit(new CommandAPDU(
        0x80, 0x10, 0x00, 0x00, new byte[] { (byte)0x12, (byte)0x34 }));

您如何为AID提供值?

这取决于您的应用场景。

  • 在您完全控制HCE侧和阅读器侧的闭环场景中,您可以选择任意(注意are some rules for AIDs} AID并将其分配给您HCE应用程序您可以稍后在阅读器应用程序中使用该AID来解决HCE应用程序。

  • 在实际的HCE场景中,您经常将HCE应用程序设计为与现有的阅读器基础架构进行交互。因此,您的HCE应用程序将实现一些给定的规范。在这种情况下,此类规范将规定您的HCE应用程序需要使用的AID(或AID)才能被现有的读取器基础结构发现。这种规范的一个例子是非接触式支付系统的EMV规范。

为什么有些HCE应用程序注册了多个AID?

有时需要通过多个&#34;名称来解决应用程序问题。 (艾滋病)。原因可能是:

  • 应用程序提供多个不同的接口(即具有不同的命令集或提供不同的数据)。
  • 现有读者使用(出于某种原因)不同的AID来处理同一个应用程序。

您如何选择AID?

智能卡应用程序标识符(AID)的规则在ISO / IEC 7816-4中定义。 AID至少有5个字节,最多可包含16个字节(有关AID大小限制,请参阅this answer)。基于前4位,AID被分成不同的组。 ISO / IEC 7816-4中定义的最相关的组是:

  • 'A'开头的AID:国际注册的AID
  • 'D'开头的AID:全国注册的AID
  • 'F'开头的AID:专有AID(无注册)

对于(国际)国家注册的AID,AID分为两部分,一个5字节的强制性RID(注册应用程序提供者标识符)和一个最多11个字节的可选PIX(专有应用程序标识符扩展)。

对于专有AID(F...),您可以使用任意值。

为什么AID F00000000A0101F0010203040506不起作用时有效?

我不知道,您没有提供足够的信息来诊断这一点。例如。当您尝试选择F0010203040506时,adb日志中是否有任何消息?

无论如何,两个AID都是有效的并且应该有效。一种可能是您已经在设备上安装了另一个注册该AID的HCE应用程序。在这种情况下,两个应用程序将听取相同的名称,这是不可能的。