12

I'm trying to do Host card emulation on an Android device using this example using ACR1281U NFC tag reader.

This is the kind of application I want to make.

As per the Android documentation and the example, it is required to register an AID in 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:description="@string/aiddescription"
               android:category="other">
        <aid-filter android:name="F0010203040506"/>
        <aid-filter android:name="F0394148148100"/>
    </aid-group>
</host-apdu-service>

How do I know which AID I need to register in my Android application so that the reader can read the HCE Android app?

Here is another question I posted regarding the same: No supported card terminal found ARC1281U nfc card reader

I have referred to the following links, but there were not of much help:

Please help as there is very little resources available on HCE!

EDIT

The example uses the AID F0010203040506 in the SELECT (by AID) command but my ACR128 reader was unable to read the HCE device.

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;
}

Then I changed the AID to F00000000A0101 (which was used by some other example app) and used this in AID filter as well. After changing to this AID, the ACR reader was able to detect the HCE device.

  • Both of the AIDs (the one used in example that did not work and another that was used in the app which worked) conform to the specification, how to I know which AID to use?
  • The example adds multiple AIDs in the AID filter but sends only one of them in the SELECT (by AID) APDU. Should I also add multiple AIDs in the AID filter? What is its use?
Michael Roland
  • 36,432
  • 10
  • 81
  • 168
Rachita Nanda
  • 4,171
  • 8
  • 39
  • 63

1 Answers1

25

The AID is a "name" that you assign to your smartcard application (in the case of HCE: the Android app that emulates the card application). A reader application uses this "name" to address your card (HCE) application with a SELECT (by DF name/AID) APDU command (see ISO/IEC 7816-4). You can use any value you want as long as it conforms to ISO/IEC 7816-4.

In your specific case, the reader example application uses the AID F0010203040506

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

Therefore, to be interoperable with that example, you need to register your HCE service for the AID F0010203040506.

How do you assign and use an AID?

Typically, you first define a "name" for your HCE app:

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

Later, reader applications can use that name to select your HCE app and to then communicate with it (in Java e.g. using Java Smart Card 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 }));

How do you come up with a value for an AID?

This depends on your application scenario.

  • In your closed-loop scenario, where you are under full control of both the HCE side and the reader side, you can choose an arbitrary (note that there are some rules for AIDs) AID and assign it to your HCE app. You can later use that AID in your reader application to address the HCE app.

  • In real-world HCE scenarios, you often design your HCE app to interact with an existing reader infrastructure. Consequently, your HCE app will implement some given specification. In that case, such a specification will dictate the AID (or AIDs) that your HCE app needs to use in order to be discoverable by the existing reader infrastructure. An example for such a specification is the EMV specification for contactless payment systems.

Why are some HCE applications registered for multiple AIDs?

Sometimes there is the need that an application is addressable through multiple "names" (AIDs). Reasons could be:

  • An application provides multiple different interfaces (i.e. that have a different command set or provide different data).
  • There are existing readers that use (for some reason) different AIDs to address the same application.

How do you choose an AID?

The rules for smartcard application identifiers (AIDs) are defined in ISO/IEC 7816-4. An AID has at least 5 bytes and may consist of up to 16 bytes (see this answer on AID size restrictions). Based on the first 4 bits, AIDs are divided into different groups. The most relevant groups defined in ISO/IEC 7816-4 are:

  • AIDs starting with 'A': internationally registered AIDs
  • AIDs starting with 'D': nationally registered AIDs
  • AIDs starting with 'F': proprietary AIDs (no registration)

For (inter)nationally registered AIDs, the AID is split into two parts, a 5-byte mandatory RID (registered application provider identifier), and an optional PIX (proprietary application identifier extension) of up to 11 bytes.

For proprietary AIDs (F...), you can use any arbitrary value.

Why did the AID F00000000A0101 work while F0010203040506 did not work?

I don't know and you did not provide sufficient information to diagnose this. E.g. where there any messages in adb log when you tried to select F0010203040506?

Anyways, both AIDs are valid and should work. One possibility could be that you already had another HCE application installed on your device that registered for that AID. In that case, two applications would have listened for the same name which is not possible.

Community
  • 1
  • 1
Michael Roland
  • 36,432
  • 10
  • 81
  • 168
  • thanks , can you please help and answer my doubt that I have added in the EDIT as the AID you mention did not work – Rachita Nanda Jan 18 '15 at 08:00
  • 1
    @Michael: When you say AID should be assigned to your application, did you mean on Android application running on phone which is expected to emulate card or you meant AID should be assigned to window application or something which is reading RFID cards continuously? – Shantanu Gupta Jan 18 '15 at 21:32
  • @MichaelRoland: I meant assigning AID to window application. I am not able to figure that out. But with your piece of code, I will try and research all possibilities. – Shantanu Gupta Jan 21 '15 at 10:56
  • @ShantanuGupta You do not "assign" the AID to a reader application. A reader application *uses* an AID to *select* a card application. – Michael Roland Jan 21 '15 at 12:26
  • @MichaelRoland: Does that mean, I need to broadcast AID from reader application and android application which has registered itself with Android OS will receive packets broadcasted by reader application. Am I on the right track? – Shantanu Gupta Jan 21 '15 at 12:49
  • If you replace "broadcast" with "send" then yes. That's how smartcard communication works: A reader device detects a card and notifies the reader application about this. The reader application then starts by selecting an application (i.e. sends a SELECT command with an AID). The Android device then receives this SELECT command and checks if it contains a HCE app that is registered for this AID. If that's the case all further communication will be forwared to this HCE app. – Michael Roland Jan 21 '15 at 13:38
  • @MichaelRoland: Does that mean, first communication packet is initiated by android application and is sent to reader application. Then reader captures this packet and sends AID to android application. Is it the case? – Shantanu Gupta Jan 22 '15 at 08:01
  • @ShantanuGupta No, that's not the case. I strongly recommend that you familiarize yourself with the concepts of the ISO/IEC 14443 standard (framing, anti-collision/enumeration, protocol activation, etc). Good literature on that topic is e.g. Finkenzeller's *RFID handbook*. A good/useful answer to this would be to broad for this commenting thread and is certainly completely off-topic with regard to Rachita Nanda's question. – Michael Roland Jan 22 '15 at 19:35
  • @MichaelRoland: Thanks for your help :) I will go through this book – Shantanu Gupta Jan 23 '15 at 02:58