Hostbasierte Kartenemulation – Übersicht

Viele Android-Geräte mit NFC-Funktion unterstützen die NFC-Kartenemulation bereits. In den meisten Fällen wird die Karte durch einen separaten Chip auf dem Gerät emuliert, der als Secure Element bezeichnet wird. Viele SIM-Karten von Mobilfunkanbietern enthalten auch ein Secure Element.

Android 4.4 und höher bieten eine zusätzliche Methode der Kartenemulation, die kein Secure Element beinhaltet: die hostbasierte Kartenemulation. Dadurch kann jede Android-App eine Karte emulieren und direkt mit dem NFC-Lesegerät kommunizieren. In diesem Artikel wird beschrieben, wie die hostbasierte Kartenemulation (Host-based Card Emulation, HCE) unter Android funktioniert und wie Sie mit dieser Methode eine App entwickeln können, die eine NFC-Karte emuliert.

Kartenemulation mit einem Secure Element

Wenn die NFC-Kartenemulation mithilfe eines Secure Element bereitgestellt wird, wird die zu emulierende Karte über eine Android-Anwendung im Secure Element auf dem Gerät bereitgestellt. Wenn der Nutzer das Gerät dann über ein NFC-Terminal hält, leitet der NFC-Controller im Gerät alle Daten vom Lesegerät direkt an das sichere Element weiter. Abbildung 1 veranschaulicht dieses Konzept:

Diagramm mit einem NFC-Lesegerät, das durch einen NFC-Controller geleitet wird, um Informationen von einem Secure Element abzurufen
Abbildung 1: NFC-Kartenemulation mit einem Secure Element.

Das Secure Element selbst führt die Kommunikation mit dem NFC-Terminal aus und an der Transaktion ist keine Android-Anwendung beteiligt. Nach Abschluss der Transaktion kann eine Android-App das Secure Element direkt nach dem Transaktionsstatus abfragen und den Nutzer benachrichtigen.

Hostbasierte Kartenemulation

Wenn eine NFC-Karte mithilfe der hostbasierten Kartenemulation emuliert wird, werden die Daten direkt an die Host-CPU und nicht an ein Secure Element weitergeleitet. In Abbildung 2 ist dargestellt, wie die hostbasierte Kartenemulation funktioniert:

Diagramm mit einem NFC-Lesegerät, das durch einen NFC-Controller geleitet wird, um Informationen von der CPU abzurufen
Abbildung 2: NFC-Kartenemulation ohne Secure Element

Unterstützte NFC-Karten und -Protokolle

Diagramm, das den HCE-Protokoll-Stack zeigt
Abbildung 3: Der HCE-Protokoll-Stack von Android.

Die NFC-Standards unterstützen viele verschiedene Protokolle. Es gibt verschiedene Arten von Karten, die Sie emulieren können.

Android 4.4 und höher unterstützt mehrere Protokolle, die derzeit gebräuchlich sind. Viele bestehende Karten für kontaktloses Bezahlen basieren bereits auf diesen Protokollen, z. B. Karten für kontaktloses Bezahlen. Diese Protokolle werden auch von vielen derzeit auf dem Markt erhältlichen NFC-Lesegeräten unterstützt, einschließlich NFC-Geräten von Android, die selbst als Lesegeräte fungieren (siehe die IsoDep-Klasse). Auf diese Weise können Sie eine End-to-End-NFC-Lösung rund um HCE entwickeln und bereitstellen, die ausschließlich Android-Geräte verwendet.

Android 4.4 und höher unterstützt die Emulation von Karten, die auf der ISO-DEP-Spezifikation des NFC-Forums (basierend auf ISO/IEC 14443-4) basieren und APDUs (Application Protocol Data Units) gemäß der Definition in der Spezifikation ISO/IEC 7816-4 verarbeiten. Android verlangt, ISO-DEP nur auf Basis der Nfc-A-Technologie (ISO/IEC 14443-3 Typ A) zu emulieren. Die Unterstützung der Nfc-B-Technologie (ISO/IEC 14443-4 Typ B) ist optional. In Abbildung 3 ist die Überlagerung all dieser Spezifikationen dargestellt.

HCE-Dienste

Die HCE-Architektur in Android basiert auf Android-Service-Komponenten (sogenannte HCE-Dienste). Einer der wichtigsten Vorteile eines Dienstes besteht darin, dass er ohne Benutzeroberfläche im Hintergrund ausgeführt werden kann. Dies ist eine gute Lösung für viele HCE-Anwendungen wie Kunden- oder Fahrkarten, für die der Nutzer keine App starten müssen sollte. Stattdessen wird durch Antippen des NFC-Lesegeräts der richtige Dienst gestartet, falls er noch nicht ausgeführt wird, und die Transaktion wird im Hintergrund ausgeführt. Natürlich steht es Ihnen kostenlos, bei Bedarf weitere UI-Elemente (z. B. Nutzerbenachrichtigungen) von Ihrem Dienst zu starten.

Dienstauswahl

Wenn der Nutzer ein Gerät an ein NFC-Lesegerät hält, muss das Android-System wissen, mit welchem HCE-Dienst das NFC-Lesegerät kommunizieren möchte. Die Spezifikation ISO/IEC 7816-4 definiert eine Methode zur Auswahl von Anwendungen, die um eine Anwendungs-ID (AID) zentriert ist. Eine AID besteht aus bis zu 16 Byte. Wenn du Karten für eine vorhandene NFC-Leseinfrastruktur emulierst, sind die AIDs, nach denen diese Leser suchen, in der Regel bekannt und öffentlich registriert (z. B. die AIDs von Zahlungsnetzwerken wie Visa und MasterCard).

Wenn du eine neue Leseinfrastruktur für deine eigene Anwendung bereitstellen möchtest, musst du deine eigenen AIDs registrieren. Das Registrierungsverfahren für AIDs ist in der Spezifikation ISO/IEC 7816-5 definiert. Wir empfehlen, eine AID gemäß 7816-5 zu registrieren, wenn Sie eine HCE-Anwendung für Android bereitstellen, da dadurch Kollisionen mit anderen Anwendungen vermieden werden.

AID-Gruppen

In einigen Fällen muss ein HCE-Dienst möglicherweise mehrere AIDs registrieren und als Standard-Handler für alle AIDs festgelegt werden, um eine bestimmte Anwendung zu implementieren. Einige AIDs in der Gruppe, die zu einem anderen Dienst führen, werden nicht unterstützt.

Eine Liste von AIDs, die zusammengehalten werden, wird als AID-Gruppe bezeichnet. Für alle AIDs in einer AID-Gruppe garantiert Android eines der folgenden Ereignisse:

  • Alle AIDs in der Gruppe werden an diesen HCE-Dienst weitergeleitet.
  • An diesen HCE-Dienst werden keine AIDs weitergeleitet (z. B. weil der Nutzer einen anderen Dienst bevorzugt hat, der auch eine oder mehrere AIDs in der Gruppe angefordert hat).

Es gibt also keinen Zwischenzustand, bei dem einige AIDs in der Gruppe an einen HCE-Dienst und andere an einen anderen weitergeleitet werden können.

AID-Gruppen und -Kategorien

Sie können jede AID-Gruppe mit einer Kategorie verknüpfen. So kann Android die Dienste von HCE-Diensten nach Kategorie gruppieren, wodurch Nutzer die Möglichkeit haben, Standardeinstellungen auf Kategorieebene statt auf AID-Ebene festzulegen. Vermeiden Sie es, AIDs in Bereichen Ihrer App zu erwähnen, die für Nutzer sichtbar sind, da sie für den durchschnittlichen Nutzer nichts bedeuten.

Android 4.4 und höher unterstützt zwei Kategorien:

HCE-Dienst implementieren

Um eine NFC-Karte mit hostbasierter Kartenemulation zu emulieren, müssen Sie eine Service-Komponente erstellen, die die NFC-Transaktionen verarbeitet.

HCE-Unterstützung prüfen

Ihre App kann prüfen, ob ein Gerät HCE unterstützt, indem sie die Funktion FEATURE_NFC_HOST_CARD_EMULATION prüft. Verwenden Sie das <uses-feature>-Tag im Manifest Ihrer App, um zu deklarieren, dass Ihre App die HCE-Funktion verwendet und ob dies für das Funktionieren der App erforderlich ist.

Dienstimplementierung

Android 4.4 und höher bietet eine praktische Service-Klasse, die Sie als Grundlage für die Implementierung eines HCE-Dienstes verwenden können: die Klasse HostApduService.

Der erste Schritt besteht darin, HostApduService zu erweitern, wie im folgenden Codebeispiel gezeigt:

Kotlin

class MyHostApduService : HostApduService() {

    override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray {
       ...
    }

    override fun onDeactivated(reason: Int) {
       ...
    }
}

Java

public class MyHostApduService extends HostApduService {
    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
       ...
    }
    @Override
    public void onDeactivated(int reason) {
       ...
    }
}

HostApduService gibt zwei abstrakte Methoden an, die überschrieben und implementiert werden müssen. Eine davon, processCommandApdu(), wird immer dann aufgerufen, wenn ein NFC-Lesegerät eine APDU (Application Protocol Data Unit) an Ihren Dienst sendet. APDUs sind in der ISO/IEC 7816-4-Spezifikation definiert. APDUs sind die Pakete auf Anwendungsebene, die zwischen dem NFC-Lesegerät und Ihrem HCE-Dienst ausgetauscht werden. Dieses Protokoll auf Anwendungsebene ist Halbduplex: Der NFC-Leser sendet Ihnen eine Befehls-APDU und wartet darauf, dass Sie eine Antwort-APDU senden.

Wie bereits erwähnt, verwendet Android die AID, um zu bestimmen, mit welchem HCE-Dienst das Leser sprechen möchte. In der Regel ist die erste APDU, die ein NFC-Lesegerät an Ihr Gerät sendet, eine SELECT AID-APDU. Diese APDU enthält die AID, mit der das Lesegerät kommunizieren möchte. Android extrahiert diese AID aus der APDU, löst sie in einen HCE-Dienst auf und leitet diese APDU dann an den aufgelösten Dienst weiter.

Du kannst eine Antwort-APDU senden, indem du die Byte der Antwort-APDU von processCommandApdu() zurückgibst. Diese Methode wird im Hauptthread der Anwendung aufgerufen und sollte nicht blockiert werden. Wenn du nicht sofort eine Antwort-APDU berechnen und zurückgeben kannst, gib null zurück. Anschließend können Sie die erforderlichen Arbeiten in einem anderen Thread ausführen und die Methode sendResponseApdu() verwenden, die in der Klasse HostApduService definiert ist, um die Antwort zu senden.

Android leitet weiter neue APDUs vom Lesegerät an deinen Dienst weiter, bis eines der folgenden Ereignisse eintritt:

  • Das NFC-Lesegerät sendet eine weitere SELECT AID-APDU, die das Betriebssystem in einen anderen Dienst auflöst.
  • Die NFC-Verbindung zwischen dem NFC-Lesegerät und Ihrem Gerät ist fehlerhaft.

In beiden Fällen wird die onDeactivated()-Implementierung Ihrer Klasse mit einem Argument aufgerufen, das angibt, welcher der beiden Fälle zutrifft.

Wenn du mit einer vorhandenen Leserinfrastruktur arbeitest, musst du das vorhandene Protokoll auf Anwendungsebene implementieren, das die Leser in deinem HCE-Dienst erwarten.

Wenn du eine neue Leseinfrastruktur bereitstellst, die du ebenfalls verwaltest, kannst du dein eigenes Protokoll und deine eigene APDU-Sequenz definieren. Versuchen Sie, die Anzahl der APDUs und die Größe der auszutauschenden Daten zu begrenzen: Dadurch wird sichergestellt, dass Ihre Nutzer ihr Gerät nur kurz über den NFC-Leser halten müssen. Eine angemessene Obergrenze liegt bei etwa 1 KB an Daten, die normalerweise innerhalb von 300 ms ausgetauscht werden können.

Erklärung des Dienstmanifests und AID-Registrierung

Sie müssen Ihren Dienst wie gewohnt im Manifest deklarieren, aber auch einige zusätzliche Informationen zur Dienstdeklaration hinzufügen:

  1. Wenn Sie der Plattform mitteilen möchten, dass es sich um einen HCE-Dienst handelt, der eine HostApduService-Schnittstelle implementiert, fügen Sie Ihrer Dienstdeklaration einen Intent-Filter für die Aktion SERVICE_INTERFACE hinzu.

  2. Um der Plattform mitzuteilen, welche AIDs-Gruppen von diesem Dienst angefordert werden, füge das <meta-data>-Tag SERVICE_META_DATA in die Deklaration des Dienstes ein, das auf eine XML-Ressource mit zusätzlichen Informationen zum HCE-Dienst verweist.

  3. Legen Sie das Attribut android:exported auf true fest und benötigen Sie die Berechtigung android.permission.BIND_NFC_SERVICE in Ihrer Dienstdeklaration. Mit Ersterem wird sichergestellt, dass der Dienst an externe Anwendungen gebunden werden kann. Dieser erzwingt dann, dass nur externe Anwendungen mit der Berechtigung android.permission.BIND_NFC_SERVICE an Ihren Dienst gebunden werden können. Da android.permission.BIND_NFC_SERVICE eine Systemberechtigung ist, erzwingt dies, dass nur das Android-Betriebssystem an Ihren Dienst gebunden werden kann.

Hier ein Beispiel für eine HostApduService-Manifestdeklaration:

<service android:name=".MyHostApduService" android:exported="true"
         android:permission="android.permission.BIND_NFC_SERVICE">
    <intent-filter>
        <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
    </intent-filter>
    <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
               android:resource="@xml/apduservice"/>
</service>

Dieses Metadaten-Tag verweist auf eine apduservice.xml-Datei. Im Folgenden finden Sie ein Beispiel für eine solche Datei mit einer einzelnen AID-Gruppendeklaration, die zwei proprietäre AIDs enthält:

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

Das <host-apdu-service>-Tag muss ein <android:description>-Attribut mit einer nutzerfreundlichen Beschreibung des Dienstes enthalten, die du auf der App-Benutzeroberfläche anzeigen lassen kannst. Mit dem Attribut requireDeviceUnlock können Sie angeben, dass das Gerät entsperrt wird, bevor Sie diesen Dienst zur Verarbeitung von APDUs aufrufen.

<host-apdu-service> muss mindestens ein <aid-group>-Tag enthalten. Jedes <aid-group>-Tag ist für folgende Zwecke erforderlich:

  • ein android:description-Attribut enthalten, das eine nutzerfreundliche Beschreibung der AID-Gruppe enthält und zur Anzeige in der UI geeignet ist
  • Legen Sie das Attribut android:category fest, um die Kategorie anzugeben, zu der die AID-Gruppe gehört, z. B. die durch CATEGORY_PAYMENT oder CATEGORY_OTHER definierten Stringkonstanten.
  • Muss ein oder mehrere <aid-filter>-Tags enthalten, von denen jedes eine einzelne AID enthält. Geben Sie die AID im Hexadezimalformat an und achten Sie darauf, dass sie eine gerade Anzahl von Zeichen enthält.

Ihre Anwendung muss außerdem die Berechtigung NFC haben, um sich als HCE-Dienst zu registrieren.

Lösung von AID-Konflikten

Es können mehrere HostApduService-Komponenten auf einem einzelnen Gerät installiert werden und dieselbe AID kann von mehr als einem Dienst registriert werden. Android löst AID-Konflikte unterschiedlich je nachdem, zu welcher Kategorie eine AID gehört. Jede Kategorie kann unterschiedliche Richtlinien zur Konfliktlösung haben.

Für einige Kategorien, z. B. für Zahlungen, kann der Nutzer möglicherweise einen Standarddienst in der UI für Android-Einstellungen auswählen. Bei anderen Kategorien könnte die Richtlinie den Nutzer im Falle eines Konflikts immer fragen, welcher Dienst aufgerufen werden soll. Informationen zum Abfragen der Richtlinie zur Konfliktlösung für eine bestimmte Kategorie finden Sie unter getSelectionModeForCategory().

Prüfen, ob Ihr Dienst als Standarddienst festgelegt ist

Anwendungen können mit der isDefaultServiceForCategory() API prüfen, ob ihr HCE-Dienst der Standarddienst für eine bestimmte Kategorie ist.

Wenn der Dienst nicht der Standarddienst ist, können Sie ihn mit ACTION_CHANGE_DEFAULT als Standarddienst festlegen.

Zahlungsanwendungen

Android betrachtet HCE-Dienste, die eine AID-Gruppe mit der Kategorie payment als Zahlungsanwendungen deklariert haben. Android 4.4 und höher enthält auf der obersten Ebene den Menüpunkt Einstellungen namens Mobil bezahlen, in dem alle diese Zahlungsanwendungen aufgelistet werden. In diesem Einstellungsmenü kann der Nutzer die Standardzahlungsanwendung auswählen, die beim Tippen auf ein Zahlungsterminal aufgerufen wird.

Erforderliche Assets für Zahlungsanwendungen

Für eine optisch ansprechendere User Experience müssen HCE-Zahlungsanwendungen ein Dienstbanner bereitstellen.

Android 13 und höher

Passen Sie die Banneranforderung in ein quadratisches Symbol an, damit sie besser in die Standardliste für die Zahlungsauswahl in der Einstellungsoberfläche passt. Idealerweise sollte es mit dem Design des App Launcher-Symbols übereinstimmen. Diese Anpassung sorgt für mehr Einheitlichkeit und ein klareres Aussehen.

Android 12 und niedriger

Lege die Größe des Dienstbanners auf 260 × 96 dp fest und lege dann die Größe des Dienstbanners in der Metadaten-XML-Datei fest. Füge dazu dem <host-apdu-service>-Tag das android:apduServiceBanner-Attribut hinzu, das auf die Drawable-Ressource verweist. Hier ein Beispiel:

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

Verhalten bei gesperrtem Bildschirm und Sperrbildschirm

Das Verhalten von HCE-Diensten variiert je nach der auf dem Gerät ausgeführten Android-Version.

Android 12 und höher

In Apps, die auf Android 12 (API-Level 31) und höher ausgerichtet sind, kannst du NFC-Zahlungen aktivieren, ohne dass der Bildschirm des Geräts eingeschaltet ist. Dazu setzt du requireDeviceScreenOn auf false.

Android 10 und höher

Geräte mit Android 10 (API-Level 29) oder höher unterstützen Sichere NFC. Wenn sichere NFC aktiviert ist, sind alle Kartenemulatoren (Host-Anwendungen und Anwendungen außerhalb des Hosts) bei ausgeschaltetem Gerätebildschirm nicht verfügbar. Wenn sichere NFC deaktiviert ist, sind Anwendungen außerhalb des Hosts verfügbar, wenn der Bildschirm des Geräts ausgeschaltet ist. Sie können mit isSecureNfcSupported() prüfen, ob sichere NFC unterstützt wird.

Auf Geräten mit Android 10 und höher gilt die gleiche Funktion zum Festlegen von android:requireDeviceUnlock auf true wie bei Geräten mit Android 9 und niedriger, aber nur, wenn sichere NFC deaktiviert ist. Das heißt, wenn sichere NFC aktiviert ist, können HCE-Dienste unabhängig von der Einstellung android:requireDeviceUnlock nicht über den Sperrbildschirm ausgeführt werden.

Android 9 und niedriger

Auf Geräten mit Android 9 (API-Level 28) und niedriger werden der NFC-Controller und der Anwendungsprozessor vollständig ausgeschaltet, wenn der Bildschirm des Geräts ausgeschaltet ist. HCE-Dienste funktionieren daher nicht, wenn der Bildschirm ausgeschaltet ist.

Unter Android 9 und niedriger können HCE-Dienste auch auf dem Sperrbildschirm verwendet werden. Dies wird jedoch über das Attribut android:requireDeviceUnlock im Tag <host-apdu-service> Ihres HCE-Dienstes gesteuert. Standardmäßig ist das Entsperren des Geräts nicht erforderlich und Ihr Dienst wird auch dann aufgerufen, wenn das Gerät gesperrt ist.

Wenn Sie das Attribut android:requireDeviceUnlock für Ihren HCE-Dienst auf true setzen, wird der Nutzer von Android in den folgenden Fällen aufgefordert, das Gerät zu entsperren:

  • hält der Nutzer ein NFC-Lesegerät an.
  • Das NFC-Lesegerät wählt eine AID aus, die zu deinem Dienst aufgelöst wurde.

Nach dem Entsperren zeigt Android ein Dialogfeld an, in dem der Nutzer aufgefordert wird, noch einmal zu tippen, um die Transaktion abzuschließen. Dies ist erforderlich, da der Nutzer das Gerät möglicherweise vom NFC-Lesegerät entfernt hat, um es zu entsperren.

Parallele Verwendung von Secure Element-Karten

Dieser Abschnitt ist für Entwickler von Interesse, die eine Anwendung bereitgestellt haben, die für die Kartenemulation ein Secure Element benötigt. Die HCE-Implementierung von Android funktioniert parallel zu anderen Methoden zur Implementierung der Kartenemulation, einschließlich der Verwendung von sicheren Elementen.

Diese Koexistenz basiert auf dem Prinzip, das als AID-Routing bezeichnet wird. Der NFC-Controller führt eine Routingtabelle, die aus einer (endlichen) Liste von Routingregeln besteht. Jede Routingregel enthält eine AID und ein Ziel. Das Ziel kann entweder die Host-CPU sein, auf der Android-Apps ausgeführt werden, oder ein verbundenes sicheres Element.

Wenn der NFC-Leser eine APDU mit einer SELECT AID sendet, parst der NFC-Controller diese und prüft, ob die AIDs mit einer AID in seiner Routingtabelle übereinstimmen. Wenn sie übereinstimmt, werden diese APDU und alle darauffolgenden APDUs an das mit der AID verknüpfte Ziel gesendet, bis eine andere SELECT AID-APDU empfangen wird oder die NFC-Verbindung unterbrochen ist.

Abbildung 4 veranschaulicht diese Architektur:

Diagramm mit einem NFC-Lesegerät, der sowohl mit einem Secure Element als auch mit der CPU kommuniziert
Abbildung 4: Android, das sowohl mit Secure Element als auch mit Hostcard-Emulation arbeitet.

Der NFC-Controller enthält normalerweise auch eine Standardroute für APDUs. Wenn in der Routingtabelle keine AID gefunden wird, wird die Standardroute verwendet. Diese Einstellung kann sich zwar von Gerät zu Gerät unterscheiden, Android-Geräte müssen jedoch dafür sorgen, dass die von Ihrer App registrierten AIDs ordnungsgemäß an den Host weitergeleitet werden.

Android-Anwendungen, die einen HCE-Dienst implementieren oder ein Secure Element verwenden, müssen sich nicht um die Konfiguration der Routingtabelle kümmern. Das wird von Android automatisch abgewickelt. Android muss lediglich wissen, welche AIDs von HCE-Diensten verarbeitet werden können und welche vom Secure Element verarbeitet werden können. Die Routingtabelle wird automatisch basierend darauf konfiguriert, welche Dienste installiert sind und welche der Nutzer als bevorzugt konfiguriert hat.

Im folgenden Abschnitt wird erläutert, wie AIDs für Anwendungen deklariert werden, die ein Secure Element für die Kartenemulation verwenden.

AID-Registrierung des Secure Element

Anwendungen, die ein Secure Element für die Kartenemulation verwenden, können in ihrem Manifest einen Off-Host-Dienst deklarieren. Die Deklaration eines solchen Dienstes ist fast identisch mit der Deklaration eines HCE-Dienstes. Es gelten folgende Ausnahmen:

  • Die im Intent-Filter verwendete Aktion muss auf SERVICE_INTERFACE festgelegt sein.
  • Das Attribut „Metadatenname“ muss auf SERVICE_META_DATA festgelegt sein.
  • Die Metadaten-XML-Datei muss das Root-Tag <offhost-apdu-service> verwenden.

    <service android:name=".MyOffHostApduService" android:exported="true"
           android:permission="android.permission.BIND_NFC_SERVICE">
      <intent-filter>
          <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
      </intent-filter>
      <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service"
                 android:resource="@xml/apduservice"/>
    </service>
    

Das folgende Beispiel zeigt die entsprechende apduservice.xml-Datei, in der zwei AIDs registriert werden:

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

Das Attribut android:requireDeviceUnlock gilt nicht für Dienste außerhalb des Hosts, da die Host-CPU nicht an der Transaktion beteiligt ist und das Secure Element daher nicht daran hindern kann, Transaktionen auszuführen, wenn das Gerät gesperrt ist.

Das Attribut android:apduServiceBanner ist für Zahlungsanwendungen außerhalb von Hosts erforderlich und kann als Standardzahlungsanwendung ausgewählt werden.

Aufruf des externen Dienstes

Android startet oder bindet sich nie an einen Dienst, der als "off-Host" deklariert ist, da die tatsächlichen Transaktionen vom Secure Element und nicht vom Android-Dienst ausgeführt werden. Die Dienstdeklaration ermöglicht Anwendungen lediglich, AIDs auf dem Secure Element zu registrieren.

HCE und Sicherheit

Die HCE-Architektur bietet ein zentrales Sicherheitselement: Da Ihr Dienst durch die Systemberechtigung BIND_NFC_SERVICE geschützt wird, kann sich nur das Betriebssystem mit Ihrem Dienst verbinden und mit ihm kommunizieren. Dadurch wird sichergestellt, dass jede APDU, die Sie empfangen, tatsächlich eine APDU ist, die vom Betriebssystem vom NFC-Controller empfangen wurde, und dass jede APDU, die Sie zurücksenden, nur an das Betriebssystem gesendet wird, das die APDUs wiederum direkt an den NFC-Controller weiterleitet.

Die letzte Frage betrifft den Zugriff auf die Daten, die Ihre App an das NFC-Lesegerät sendet. Diese ist im HCE-Design absichtlich entkoppelt. Es spielt keine Rolle, woher die Daten stammen. Es sorgt nur dafür, dass sie sicher zum NFC-Controller und zum NFC-Lesegerät übertragen werden.

Zum sicheren Speichern und Abrufen der Daten, die Sie von Ihrem HCE-Dienst senden möchten, können Sie sich beispielsweise auf die Android-Anwendungs-Sandbox verlassen, die die Daten Ihrer App von anderen Apps isoliert. Weitere Informationen zur Sicherheit bei Android finden Sie unter Sicherheitstipps.

Protokollparameter und -details

Dieser Abschnitt ist für Entwickler von Interesse, die wissen möchten, welche Protokollparameter von HCE-Geräten während der Antikollisions- und Aktivierungsphase der NFC-Protokolle verwendet werden. Dadurch kannst du eine Leseinfrastruktur aufbauen, die mit Android-HCE-Geräten kompatibel ist.

Anti-Kollision und Aktivierung des Nfc-A-Protokolls (ISO/IEC 14443 Typ A)

Bei der Aktivierung des NFC-A-Protokolls werden mehrere Frames ausgetauscht.

Im ersten Teil des Austauschs zeigt das HCE-Gerät seine UID an. Es sollte davon ausgegangen werden, dass HCE-Geräte eine zufällige UID haben. Das bedeutet, dass die UID, die dem Leser bei jedem Tippen angezeigt wird, eine zufällig generierte UID ist. Aus diesem Grund sollten NFC-Lesegeräte zur Authentifizierung oder Identifizierung nicht von der UID von HCE-Geräten abhängig sein.

Das NFC-Lesegerät kann das HCE-Gerät anschließend durch Senden eines SEL_REQ-Befehls auswählen. Für die SEL_RES-Antwort des HCE-Geräts ist mindestens das 6. Bit (0x20) festgelegt, was darauf hinweist, dass das Gerät ISO-DEP unterstützt. Beachten Sie, dass auch andere Bits im SEL_RES festgelegt werden können, um beispielsweise das NFC-DEP-Protokoll (p2p) zu unterstützen. Da andere Bits festgelegt werden können, sollten Leser, die mit HCE-Geräten interagieren möchten, explizit nur nach dem sechsten Bit suchen und nicht den vollständigen SEL_RES mit einem Wert von 0 x 20 vergleichen.

Aktivierung von ISO-DEP

Nach der Aktivierung des Nfc-A-Protokolls initiiert das NFC-Lesegerät die Aktivierung des ISO-DEP-Protokolls. Ein RATS-Befehl (Request for Answer To Select) wird gesendet. Der NFC-Controller generiert die RATS-Antwort, den ATS. Der ATS kann nicht von HCE-Diensten konfiguriert werden. HCE-Implementierungen müssen jedoch die Anforderungen des NFC-Forums für die ATS-Antwort erfüllen. Daher können sich NFC-Leser darauf verlassen, dass diese Parameter gemäß den Anforderungen des NFC-Forums für jedes HCE-Gerät festgelegt werden.

Der folgende Abschnitt enthält weitere Details zu den einzelnen Bytes der ATS-Antwort, die vom NFC-Controller auf einem HCE-Gerät zurückgegeben wird:

  • TL: Länge der ATS-Antwort. Darf nicht länger als 20 Byte sein.
  • T0: Die Bits 5, 6 und 7 müssen auf allen HCE-Geräten festgelegt sein, um anzugeben, dass TA(1), TB(1) und TC(1) in der ATS-Antwort enthalten sind. Die Bits 1 bis 4 geben die FSCI an und codieren die maximale Framegröße. Auf HCE-Geräten muss der Wert von FSCI zwischen 0 h und 8 h liegen.
  • T(A)1: Definiert die Bitraten zwischen Lesegerät und Emulator und ob sie asymmetrisch sein können. Es gibt keine Anforderungen an die Bitrate und auch keine Garantien für HCE-Geräte.
  • T(B)1: Die Bits 1 bis 4 geben die Ganzzahl für die Start-Frame Guard-Zeit an. Auf HCE-Geräten muss die SFGI-Zahl <= 8h betragen. Die Bits 5 bis 8 geben die Ganzzahl für die Frame-Wartezeit an und codieren die Frame-Wartezeit (FWT). Bei HCE-Geräten muss der FWI-Wert <= 8 h betragen.
  • T(C)1: Bit 5 gibt die Unterstützung für erweiterte Protokollfunktionen an. HCE-Geräte unterstützen „Erweiterte Protokollfunktionen“ möglicherweise nicht. Bit 2 bedeutet, dass die DID unterstützt wird. HCE-Geräte unterstützen DID möglicherweise oder nicht. Bit 1 gibt an, dass NAD unterstützt wird. HCE-Geräte dürfen NAD nicht unterstützen und Bit 1 auf null setzen.
  • Bisherige Byte: HCE-Geräte können bis zu 15 Verlaufsbyte zurückgeben. NFC-Leser, die bereit sind, mit HCE-Diensten zu interagieren, sollten keine Annahmen über den Inhalt der Verlaufsdaten oder deren Vorhandensein treffen.

Beachten Sie, dass viele HCE-Geräte wahrscheinlich mit den Protokollanforderungen kompatibel sind, die die in EMVCo vereinten Zahlungsnetzwerke in ihrer Spezifikation für das kontaktlose Kommunikationsprotokoll angegeben haben. Insbesondere

  • Der FSCI-Wert in T0 muss zwischen 2 und 8 Stunden liegen.
  • T(A)1 muss auf 0x80 gesetzt sein, um anzugeben, dass nur die Bitrate von 106 kbit/s unterstützt wird und asymmetrische Bitraten zwischen Lesegerät und Emulator nicht unterstützt werden.
  • FWI in T(B)1 muss <= 7 Std. betragen.

APDU-Datenaustausch

Wie bereits erwähnt, unterstützen HCE-Implementierungen nur einen einzelnen logischen Kanal. Der Versuch, Anwendungen auf verschiedenen logischen Kanälen auszuwählen, funktioniert auf einem HCE-Gerät nicht.