如何获得 reader 基于主机的卡仿真的 AID

How to get AID for reader Host based card emulation

我正在尝试 Host card emulation on an Android device using this example 使用 ACR1281U NFC 标签 reader.

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,以便 reader 可以读取 HCE Android应用程序?

这是我发布的关于相同问题的另一个问题:

我参考了以下链接,但没有太大帮助:

请帮忙,因为 HCE 上可用的资源很少!

编辑

该示例在 SELECT(通过 AID)命令中使用了 AID F0010203040506,但我的 ACR128 reader 无法读取 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 reader 能够检测到 HCE 设备。

AID 是您分配给智能卡应用程序的 "name"(在 HCE 的情况下:模拟卡应用程序的 Android 应用程序)。 reader 应用程序使用此 "name" 通过 SELECT(通过 DF name/AID)APDU 命令寻址您的卡 (HCE) 应用程序(参见 ISO/IEC 7816-4 ).只要符合ISO/IEC7816-4.

,你可以使用任何你想要的值

在您的特定情况下,reader example application 使用 AID F0010203040506

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

因此,要与该示例互操作,您需要为 AID F0010203040506.

注册您的 HCE 服务

如何分配和使用 AID?

通常,您首先要为您的 HCE 应用程序定义 "name":

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

稍后,reader 应用程序可以将该名称用于 select 您的 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 端和 reader 端,你可以选择一个任意的(注意有 are some rules for AIDs) AID 并将其分配给您的 HCE 应用程序。您稍后可以在 reader 应用程序中使用该 AID 来处理 HCE 应用程序。

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

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

有时需要一个应用程序可以通过多个 "names" (AID) 寻址。原因可能是:

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

如何选择AID?

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

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

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

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

为什么 AID F00000000A0101 有效而 F0010203040506 无效?

我不知道,而且您没有提供足够的信息来对此进行诊断。例如。当您尝试 select F0010203040506?

时,adb 日志中的任何消息

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