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 ebenfalls ein Secure Element.

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

Kartenemulation mit einem Secure Element

Wenn die NFC-Kartenemulation über ein 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 an ein NFC-Terminal hält, leitet der NFC-Controller auf dem Gerät alle Daten vom Lesegerät direkt an das Secure Element weiter. Abbildung 1 veranschaulicht dieses Konzept:

Ein Diagramm mit einem NFC-Leser, der über einen NFC-Controller Informationen aus einem sicheren Element abruft
Abbildung 1: NFC-Kartenemulation mit einem Secure Element.

Das Secure Element selbst führt die Kommunikation mit dem NFC-Terminal aus, an der Transaktion ist keine Android-Anwendung beteiligt. Nach Abschluss der Transaktion kann eine Android-App den Transaktionsstatus direkt über das Secure Element 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. Abbildung 2 zeigt, wie die hostbasierte Kartenemulation funktioniert:

Diagramm mit einem NFC-Lesegerät, das über einen NFC-Controller Informationen von der CPU abruft
Abbildung 2: NFC-Kartenemulation ohne Secure Element.

Unterstützte NFC-Karten und -Protokolle

Diagramm mit dem HCE-Protokollstapel
Abbildung 3: HCE-Protokoll-Stack von Android

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

Android 4.4 und höher unterstützt mehrere Protokolle, die heute auf dem Markt üblich sind. Viele vorhandene Karten für kontaktloses Bezahlen basieren bereits auf diesen Protokollen, z. B. Karten für kontaktloses Bezahlen. Diese Protokolle werden auch von vielen NFC-Lesegeräten auf dem Markt unterstützt, einschließlich Android-NFC-Geräten, die selbst als Lesegeräte fungieren (siehe Klasse IsoDep). So können Sie eine End-to-End-NFC-Lösung für HCE mit nur Android-Geräten erstellen und bereitstellen.

Insbesondere werden mit Android 4.4 und höher Karten emuliert, die auf der ISO-DEP-Spezifikation des NFC-Forums (basierend auf ISO/IEC 14443-4) basieren und Application Protocol Data Units (APDUs) gemäß der ISO/IEC 7816-4-Spezifikation verarbeiten. Android erfordert die Emulation von ISO-DEP nur über die NFC-A-Technologie (ISO/IEC 14443-3 Typ A). Die Unterstützung der NFC-B-Technologie (ISO/IEC 14443-4 Typ B) ist optional. In Abbildung 3 sehen Sie, wie diese Spezifikationen übereinandergelegt werden.

HCE-Dienste

Die HCE-Architektur in Android basiert auf Service-Komponenten von Android, die als HCE-Dienste bezeichnet werden. Einer der Hauptvorteile eines Dienstes besteht darin, dass er ohne Benutzeroberfläche im Hintergrund ausgeführt werden kann. Das ist eine gute Lösung für viele HCE-Anwendungen wie Kundenkarten oder Fahrkarten, für die der Nutzer keine App starten muss. Stattdessen wird durch das Anhalten des Geräts an den NFC-Leser der richtige Dienst gestartet, falls er noch nicht ausgeführt wird, und die Transaktion wird im Hintergrund ausgeführt. Natürlich können Sie bei Bedarf zusätzliche UI (z. B. Nutzerbenachrichtigungen) von Ihrem Dienst starten.

Dienstauswahl

Wenn der Nutzer ein Gerät an ein NFC-Lesegerät hält, muss das Android-System wissen, mit welchem HCE-Dienst der NFC-Leser kommunizieren möchte. Die ISO/IEC 7816-4-Spezifikation definiert eine Möglichkeit zur Auswahl von Anwendungen rund um eine Anwendungs-ID (AID). Eine AID besteht aus bis zu 16 Byte. Wenn du Karten für eine vorhandene NFC-Leser-Infrastruktur 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 Sie eine neue Leseinfrastruktur für Ihre eigene Anwendung bereitstellen möchten, müssen Sie Ihre eigenen AIDs registrieren. Das Registrierungsverfahren für AIDs ist in der ISO/IEC 7816-5-Spezifikation definiert. Wir empfehlen, eine AID gemäß 7816-5 zu registrieren, wenn Sie eine HCE-Anwendung für Android bereitstellen, da dadurch Konflikte 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 weitergeleitet werden, 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 Folgendes:

  • Alle AIDs in der Gruppe werden an diesen HCE-Dienst weitergeleitet.
  • Keine AIDs in der Gruppe werden an diesen HCE-Dienst weitergeleitet, z. B. weil der Nutzer einen anderen Dienst bevorzugt hat, für den auch eine oder mehrere AIDs in Ihrer Gruppe angefordert wurden.

Mit anderen Worten: Es gibt keinen Zwischenstatus, 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 einer Kategorie zuordnen. So können HCE-Dienste in Android nach Kategorie gruppiert werden. Dadurch kann der Nutzer Standardeinstellungen auf Kategorieebene statt auf AID-Ebene festlegen. Erwähnen Sie AIDs nicht in nutzerorientierten Teilen Ihrer App, da sie für den durchschnittlichen Nutzer keine Bedeutung haben.

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

HCE-Dienst implementieren

Wenn Sie eine NFC-Karte mithilfe der hostbasierten Kartenemulation emulieren möchten, müssen Sie eine Service-Komponente erstellen, die die NFC-Transaktionen verarbeitet.

HCE-Unterstützung prüfen

Ihre Anwendung kann prüfen, ob ein Gerät HCE unterstützt. Dazu wird nach der Funktion FEATURE_NFC_HOST_CARD_EMULATION gesucht. Verwenden Sie das Tag <uses-feature> im Manifest Ihrer Anwendung, um anzugeben, dass Ihre App die HCE-Funktion verwendet und ob sie für die Funktion 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.

Im ersten Schritt wird HostApduService erweitert, 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 deklariert zwei abstrakte Methoden, die Sie überschreiben und implementieren müssen. Eine davon, processCommandApdu(), wird aufgerufen, wenn ein NFC-Lesegerät eine Application Protocol Data Unit (APDU) 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 ermitteln, mit welchem HCE-Dienst der Leser kommunizieren möchte. Normalerweise 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 der Leser kommunizieren möchte. Android extrahiert diese AID aus der APDU, löst sie in einen HCE-Dienst auf und leitet die APDU dann an den aufgelösten Dienst weiter.

Sie können eine Antwort-APDU senden, indem Sie die Byte der Antwort-APDU aus processCommandApdu() zurückgeben. Diese Methode wird im Hauptthread Ihrer Anwendung aufgerufen, den Sie nicht blockieren sollten. Wenn Sie eine Antwort-APDU nicht sofort berechnen und zurückgeben können, geben Sie null zurück. Sie können dann die erforderlichen Aufgaben in einem anderen Thread ausführen und die in der Klasse HostApduService definierte Methode sendResponseApdu() verwenden, um die Antwort zu senden, wenn Sie fertig sind.

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

  • Der NFC-Leser sendet eine weitere SELECT AID-APDU, die vom Betriebssystem auf einen anderen Dienst aufgelöst wird.
  • Die NFC-Verbindung zwischen dem NFC-Lesegerät und Ihrem Gerät ist unterbrochen.

In beiden Fällen wird die onDeactivated()-Implementierung Ihrer Klasse mit einem Argument aufgerufen, das angibt, was passiert ist.

Wenn Sie mit einer vorhandenen Lesegeräteinfrastruktur arbeiten, müssen Sie das vorhandene Protokoll auf Anwendungsebene implementieren, das die Lesegeräte in Ihrem HCE-Dienst erwarten.

Wenn Sie eine neue Leserinfrastruktur bereitstellen, die Sie auch steuern, können Sie Ihr eigenes Protokoll und Ihre eigene APDU-Sequenz definieren. Begrenzen Sie die Anzahl der APDUs und die Größe der auszutauschenden Daten. So müssen Nutzer ihr Gerät nur kurz über den NFC-Leser halten. Eine angemessene Obergrenze liegt bei etwa 1 KB an Daten, die normalerweise innerhalb von 300 ms ausgetauscht werden können.

Erklärung zum Servicemanifest und AID-Registrierung

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

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

  2. Wenn Sie der Plattform mitteilen möchten, welche AID-Gruppen von diesem Dienst angefordert werden, fügen Sie der Deklaration des Dienstes das Tag SERVICE_META_DATA <meta-data> hinzu, das auf eine XML-Ressource mit zusätzlichen Informationen zum HCE-Dienst verweist.

  3. Legen Sie das android:exported-Attribut auf true fest und fordern Sie in Ihrer Diensterklärung die Berechtigung android.permission.BIND_NFC_SERVICE an. Mit Ersterem wird sichergestellt, dass der Dienst an externe Anwendungen gebunden werden kann. Letzteres erzwingt dann, dass nur externe Anwendungen, die die Berechtigung android.permission.BIND_NFC_SERVICE haben, an Ihren Dienst gebunden werden können. Da android.permission.BIND_NFC_SERVICE eine Systemberechtigung ist, kann nur das Android-Betriebssystem eine Bindung an Ihren Dienst vornehmen.

Das folgende Beispiel zeigt die Deklaration des Manifests HostApduService:

<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 das Attribut <android:description> enthalten, das eine nutzerfreundliche Beschreibung des Dienstes enthält, die in der App-Benutzeroberfläche angezeigt werden kann. Mit dem Attribut requireDeviceUnlock können Sie angeben, dass das Gerät entsperrt ist, bevor Sie diesen Dienst zum Bearbeiten von APDUs aufrufen.

Das <host-apdu-service>-Element muss mindestens ein <aid-group>-Tag enthalten. Für jedes <aid-group>-Tag gilt Folgendes:

  • ein android:description-Attribut enthalten, das eine nutzerfreundliche Beschreibung der AID-Gruppe enthält, die in der UI angezeigt werden kann.
  • Das Attribut android:category muss so festgelegt sein, dass es die Kategorie angibt, zu der die AID-Gruppe gehört, z. B. die mit CATEGORY_PAYMENT oder CATEGORY_OTHER definierten Stringkonstanten.
  • 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.

AID-Konfliktlösung

Es können mehrere HostApduService-Komponenten auf einem einzelnen Gerät installiert sein und dieselbe AID kann von mehreren Diensten registriert werden. Android bestimmt anhand der folgenden Schritte, welcher Dienst aufgerufen werden soll:

  1. Wenn die ausgewählte Standard-Wallet-App des Nutzers die AID registriert hat, wird diese App aufgerufen.
  2. Wenn die Standard-Wallet-App die AID nicht registriert hat, wird der Dienst aufgerufen, der die AID registriert hat.
  3. Wenn die AID von mehreren Diensten registriert wurde, wird der Nutzer von Android gefragt, welchen Dienst er aufrufen möchte.

Prüfen, ob Ihre App die Standard-Wallet-App ist

Apps können prüfen, ob sie die Standard-Wallet-App sind, indem sie RoleManager.ROLE_WALLET an RoleManager.isRoleHeld() übergeben.

Wenn deine App nicht die Standard-App ist, kannst du die Standard-Wallet-Rolle anfordern, indem du RoleManager.ROLE_WALLET an RoleManager.createRequestRoleIntent() übergibst.

Wallet-Apps

Android betrachtet HCE-Dienste, die eine AID-Gruppe mit der Zahlungskategorie deklariert haben, als Wallet-Anwendungen. Android 15 und höher enthält eine Standardrolle für Wallet-Apps, die Nutzer unter Einstellungen > Apps > Standard-Apps auswählen können. Damit wird die Standard-Wallet-Anwendung definiert, die aufgerufen wird, wenn ein Zahlungsterminal an das Terminal gehalten wird.

Erforderliche Assets für Wallet-Apps

Für eine visuell ansprechendere Nutzererfahrung müssen HCE-Wallet-Apps ein Servicebanner enthalten.

Android 13 oder höher

Passen Sie die Banneranforderung an ein quadratisches Symbol an, damit es besser in die Standardauswahlliste für Zahlungen in der Benutzeroberfläche der Einstellungen passt. Idealerweise sollte es mit dem Design des App Launcher-Symbols identisch sein. Dadurch wird für mehr Einheitlichkeit und ein klareres Erscheinungsbild gesorgt.

Android 12 und niedriger

Legen Sie die Größe des Dienstbanners auf 260 × 96 dp fest und legen Sie dann die Größe des Dienstbanners in Ihrer Metadaten-XML-Datei fest, indem Sie dem Tag <host-apdu-service>, das auf die Zeichnensressource verweist, das Attribut android:apduServiceBanner hinzufügen. 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>

Beobachtungsmodus

Mit Android 15 wird der Beobachtungsmodus eingeführt. Wenn der Beobachtungsmodus aktiviert ist, kann das Gerät NFC-Abfrageschleifen beobachten und Benachrichtigungen dazu an die entsprechenden HostApduService-Komponenten senden, damit sie sich auf die Interaktion mit einem bestimmten NFC-Terminal vorbereiten können. Ein HostApduService kann das Gerät in den Beobachtungsmodus versetzen, indem es true an setObserveModeEnabled() übergibt. Dadurch wird der NFC-Stack angewiesen, NFC-Transaktionen nicht zuzulassen und stattdessen Polling-Schleifen passiv zu beobachten.

Abfrageschleifenfilter

Sie können Polling-Loop-Filter für eine HostApduService mit einer der folgenden Methoden registrieren:

Wenn ein Polling-Loop-Filter mit nicht standardmäßigen Polling-Frames übereinstimmt, leitet der NFC-Stack diese Polling-Frames an die entsprechende HostApduService weiter, indem er die Methode processPollingFrames() aufruft. So kann der Dienst alle erforderlichen Schritte ausführen, um sicherzustellen, dass der Nutzer bereit ist, eine Transaktion auszuführen, und dies auch beabsichtigt – z. B. durch Authentifizierung des Nutzers. Wenn ein NFC-Leser nur Standardframes in seinem Polling-Loop verwendet, leitet der NFC-Stack diese Polling-Frames an den bevorzugten Dienst im Vordergrund weiter, wenn sich dieser Dienst im Vordergrund befindet, andernfalls an den Standardinhaber der Wallet-Rolle.

Polling-Frame-Benachrichtigungen enthalten auch eine anbieterspezifische Messung der Feldstärke, die Sie durch Aufrufen von getVendorSpecificGain() abrufen können. Anbieter können Messungen mit ihrer eigenen Skala bereitstellen, solange sie in ein einzelnes Byte passen.

Auf Polling-Schleifen reagieren und den Beobachtungsmodus beenden

Wenn der Dienst für Transaktionen bereit ist, kann er den Beobachtungsmodus beenden, indem er false an setObserveModeEnabled() übergibt. Der NFC-Stack ermöglicht dann die Fortsetzung der Transaktionen.

HostApduService-Komponenten können angeben, dass der Beobachtungsmodus aktiviert werden soll, wenn sie der bevorzugte Zahlungsdienst sind. Dazu müssen sie im Manifest shouldDefaultToObserveMode auf true setzen oder CardEmulation.setShouldDefaultToObserveModeForService() aufrufen.

Mit den Komponenten HostApduService und OffHostApduService können Sie auch angeben, dass Polling-Loop-Filter, die mit empfangenen Polling-Loop-Frames übereinstimmen, den Beobachtungsmodus automatisch deaktivieren und Transaktionen fortsetzen sollen. Dazu müssen Sie in der PollingLoopFilter-Deklaration im Manifest autoTransact auf true festlegen.

Verhalten bei ausgeschaltetem Display und Sperrbildschirm

Das Verhalten von HCE-Diensten hängt von der Android-Version ab, die auf dem Gerät ausgeführt wird.

Android 12 und höher

In Apps, die auf Android 12 (API-Level 31) und höher ausgerichtet sind, können Sie NFC-Zahlungen aktivieren, ohne dass das Display des Geräts eingeschaltet ist. Legen Sie dazu requireDeviceScreenOn auf false fest.

Android 10 und höher

Geräte mit Android 10 (API-Level 29) oder höher unterstützen Secure NFC. Wenn Secure NFC aktiviert ist, sind alle Kartenemulatoren (Host- und Off-Host-Anwendungen) nicht verfügbar, wenn der Gerätebildschirm ausgeschaltet ist. Wenn sichere NFC deaktiviert ist, sind Anwendungen außerhalb des Hosts verfügbar, wenn der Gerätebildschirm ausgeschaltet ist. Mit isSecureNfcSupported() können Sie 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 auf Geräten mit Android 9 und niedriger, jedoch nur, wenn sichere NFC deaktiviert ist. Das heißt, wenn sichere NFC aktiviert ist, können HCE-Dienste unabhängig von der Einstellung von android:requireDeviceUnlock nicht über den Sperrbildschirm funktionieren.

Android 9 und niedriger

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

Auch unter Android 9 und niedriger können HCE-Dienste über den Sperrbildschirm funktionieren. Dies wird jedoch durch das Attribut android:requireDeviceUnlock im <host-apdu-service>-Tag 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 festlegen, wird der Nutzer von Android aufgefordert, das Gerät zu entsperren, wenn Folgendes geschieht:

  • tippt der Nutzer auf ein NFC-Lesegerät.
  • wählt das NFC-Lesegerät eine AID aus, die Ihrem Dienst zugeordnet wird.

Nach dem Entsperren wird auf Android-Geräten ein Dialogfeld angezeigt, in dem der Nutzer aufgefordert wird, noch einmal zu tippen, um die Transaktion abzuschließen. Das ist notwendig, da der Nutzer das Gerät möglicherweise vom NFC-Lesegerät weg bewegt hat, um es zu entsperren.

Koexistenz mit Secure Element-Karten

Dieser Abschnitt ist für Entwickler interessant, die eine Anwendung bereitgestellt haben, die für die Kartenemulation auf ein Secure Element angewiesen ist. Die HCE-Implementierung von Android ist so konzipiert, dass sie parallel zu anderen Methoden zur Implementierung der Kartenemulation funktioniert, einschließlich der Verwendung von Secure Elements.

Diese Koexistenz basiert auf dem Prinzip des AID-Routings. Der NFC-Controller verwaltet 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, wird sie vom NFC-Controller analysiert und geprüft, ob die AIDs mit einer AID in der Routingtabelle übereinstimmen. Wenn sie übereinstimmen, werden diese APDU und alle nachfolgenden APDUs an das mit der AID verknüpfte Ziel gesendet, bis eine weitere SELECT AID-APDU empfangen wird oder die NFC-Verbindung unterbrochen wird.

Abbildung 4 zeigt diese Architektur:

Diagramm mit NFC-Lesegerät, das sowohl mit einem sicheren Element als auch mit der CPU kommuniziert
Abbildung 4: Android-Betriebssystem, das sowohl mit Secure Element als auch mit Host-Kartenemulation funktioniert

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

Für Android-Anwendungen, die einen HCE-Dienst implementieren oder ein Secure Element verwenden, muss die Routingtabelle nicht konfiguriert werden. Diese wird von Android automatisch ausgeführt. Android muss lediglich wissen, welche AIDs von HCE-Diensten und welche vom Secure Element verarbeitet werden können. Die Routingtabelle wird automatisch anhand der installierten Dienste und der vom Nutzer als bevorzugt konfigurierten Dienste konfiguriert.

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

AID-Registrierung für 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 nahezu 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 für den Metadatennamen muss auf SERVICE_META_DATA festgelegt sein.
  • Die Metadaten-XML-Datei muss das Stamm-<offhost-apdu-service>-Tag 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>

Im Folgenden finden Sie ein Beispiel für die entsprechende apduservice.xml-Datei, in der zwei AIDs registriert sind:

<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 daher nicht verhindern kann, dass das Secure Element Transaktionen ausführt, wenn das Gerät gesperrt ist.

Das Attribut android:apduServiceBanner ist für Off-Host-Dienste erforderlich, die Zahlungsanwendungen sind und als Standard-Zahlungsanwendung ausgewählt werden können.

Aufruf von Diensten außerhalb des Hosts

Android startet nie einen Dienst, der als „außerhalb des Hosts“ deklariert ist, oder bindet sich nicht an diesen, da die tatsächlichen Transaktionen vom Secure Element und nicht vom Android-Dienst ausgeführt werden. Die Dienstdeklaration erlaubt Anwendungen lediglich, AIDs zu registrieren, die auf dem Secure Element vorhanden sind.

HCE und Sicherheit

Die HCE-Architektur bietet einen wichtigen Sicherheitsaspekt: Da Ihr Dienst durch die Systemberechtigung BIND_NFC_SERVICE geschützt ist, kann nur das Betriebssystem eine Bindung an Ihren Dienst herstellen und mit ihm kommunizieren. Dadurch wird sichergestellt, dass jede empfangene APDU tatsächlich eine APDU ist, die vom Betriebssystem vom NFC-Controller empfangen wurde. Jede APDU, die Sie zurücksenden, geht nur an das Betriebssystem, das wiederum die APDUs direkt an den NFC-Controller weiterleitet.

Die letzte verbleibende Frage ist, woher Sie die Daten erhalten, die Ihre App an den NFC-Leser sendet. Im HCE-Design ist dies bewusst voneinander getrennt. Es spielt keine Rolle, woher die Daten stammen, es wird nur dafür gesorgt, dass sie sicher an den NFC-Controller und an den NFC-Leser übertragen werden.

Zum sicheren Speichern und Abrufen der Daten, die Sie über Ihren HCE-Dienst senden möchten, können Sie beispielsweise die Android Application Sandbox verwenden, 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 HCE-Geräte während der Anti-Collision- und Aktivierungsphasen der NFC-Protokolle verwenden. So lässt sich eine Lesegeräteinfrastruktur erstellen, die mit Android-HCE-Geräten kompatibel ist.

NFC-A-Protokoll Antikollision und Aktivierung (ISO/IEC 14443 Typ A)

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

Im ersten Teil des Datenaustauschs gibt das HCE-Gerät seine UID an. Bei HCE-Geräten sollte davon ausgegangen werden, dass sie eine zufällige UID haben. Das bedeutet, dass die UID, die dem Leser angezeigt wird, bei jedem Tippen 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.

Der NFC-Leser kann das HCE-Gerät anschließend durch Senden eines SEL_REQ-Befehls auswählen. In der SEL_RES-Antwort des HCE-Geräts ist mindestens das 6. Bit (0x20) gesetzt, was bedeutet, dass das Gerät ISO-DEP unterstützt. Andere Bits in der SEL_RES können ebenfalls gesetzt sein, was beispielsweise die Unterstützung des NFC-DEP-Protokolls (p2p) angibt. Da andere Bits gesetzt sein können, sollten Leser, die mit HCE-Geräten interagieren möchten, nur explizit das sechste Bit prüfen und nicht die gesamte SEL_RES mit einem Wert von 0x20 vergleichen.

ISO-DEP-Aktivierung

Nachdem das NFC-A-Protokoll aktiviert wurde, initiiert der NFC-Leser die Aktivierung des ISO-DEP-Protokolls. Es wird ein RATS-Befehl (Request for Answer To Select) gesendet. Der NFC-Controller generiert die RATS-Antwort, die ATS. Die 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, sodass NFC-Leser auf diese Parameter zählen können, wenn sie gemäß den Anforderungen des NFC-Forums für jedes HCE-Gerät festgelegt werden.

Im folgenden Abschnitt finden Sie weitere Informationen zu den einzelnen Byte der ATS-Antwort, die vom NFC-Controller auf einem HCE-Gerät bereitgestellt wird:

  • TL: Länge der ATS-Antwort. Die Länge darf nicht größer als 20 Byte sein.
  • T0: Bits 5, 6 und 7 müssen auf allen HCE-Geräten gesetzt sein, was bedeutet, 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 und 8 Stunden liegen.
  • T(A)1: definiert die Bitrate zwischen Lesegerät und Emulator und ob sie asymmetrisch sein kann. Für HCE-Geräte gelten keine Bitratenanforderungen oder -garantien.
  • T(B)1: Bits 1 bis 4 geben die Ganzzahl für die Start Frame Guard Time (SFGI) an. Auf HCE-Geräten muss die SFGI <= 8 Stunden betragen. Die Bits 5 bis 8 geben die Ganzzahl für die Frame-Wartezeit (Frame Waiting Time Integer, FWI) an und codieren die Frame-Wartezeit (Frame Waiting Time, FWT). Auf HCE-Geräten muss FWI <= 8 h sein.
  • T(C)1: Bit 5 gibt die Unterstützung für „Erweiterte Protokollfunktionen“ an. HCE-Geräte unterstützen möglicherweise erweiterte Protokollfunktionen. Bit 2 gibt an, dass „DID“ unterstützt wird. HCE-Geräte unterstützen DID möglicherweise nicht. Bit 1 gibt an, dass NAD unterstützt wird. HCE-Geräte dürfen NAD nicht unterstützen und müssen Bit 1 auf Null setzen.
  • Bisherige Byte: HCE-Geräte können bis zu 15 Verlaufsbyte zurückgeben. NFC-Lesegeräte, die mit HCE-Diensten interagieren möchten, dürfen keine Annahmen über den Inhalt der bisherigen Bytes oder deren Vorhandensein treffen.

Beachten Sie, dass viele HCE-Geräte wahrscheinlich die Protokollanforderungen erfüllen, die die in EMVCo vereinten Zahlungsnetzwerke in ihrer Spezifikation für das Contactless Communication Protocol festgelegt haben. Insbesondere

  • FSCI in T0 muss zwischen 2 und 8 Stunden liegen.
  • T(A)1 muss auf 0x80 gesetzt sein, was bedeutet, 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 Stunden sein.

APDU-Datenaustausch

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