Wie emuliert eine Android-Anwendung eine Karte mit Host Card Emulation?
Mit einem Dienst, der HostApduService erweitert und APDU beantwortet, im Manifest deklariert mit dem Absichtsfilter der Kartenemulation, der Berechtigung BIND_NFC_SERVICE und einer XML-Datei, die seine Anwendungskennungen in einer Kategorie einträgt. Android startet den Dienst beim Antippen, auch wenn die Anwendung geschlossen ist.
Der Dienst und seine zwei Methoden
Die Emulation lebt in einem Dienst, nicht in einer Aktivität. Androids Leitfaden zur Kartenemulation baut den Mechanismus auf HostApduService, der im Hintergrund läuft: Ein Antippen startet ihn, wenn er nicht läuft, und der Vorgang geschieht, ohne dass die Anwendung geöffnet wird. Prüfen Sie FEATURE_NFC_HOST_CARD_EMULATION, bevor Sie sich darauf verlassen, und deklarieren Sie es im Manifest mit uses-feature.
Die Klasse hat zwei Methoden umzusetzen. processCommandApdu() wird für jede APDU aufgerufen, die das Lesegerät sendet, und gibt die Bytes der Antwort zurück. Sie läuft im Hauptthread, eine Antwort, die Arbeit kostet, gibt also null zurück und kommt später über sendResponseApdu() aus einem anderen Thread. onDeactivated() wird aufgerufen, wenn das Lesegerät eine Kennung auswählt, die zu einem anderen Dienst führt, oder wenn die Funkverbindung abreißt, und sein Argument sagt, welches von beidem geschah.
Was unterwegs ist, ist eine APDU, wie die Seite zur APDU beschreibt. Android emuliert ISO-DEP, ISO/IEC 14443-4, und verarbeitet die Befehle der ISO/IEC 7816-4; der Leitfaden schreibt ISO-DEP über NFC-A vor und lässt NFC-B frei. Der Austausch ist Halbduplex und Android unterstützt einen einzigen logischen Kanal, Befehle und Antworten wechseln sich also einzeln ab.
Was Manifest und XML deklarieren
Die Deklaration des Dienstes trägt drei Zusätze: einen Absichtsfilter für die Aktion des Host-APDU-Dienstes, die Berechtigung android.permission.BIND_NFC_SERVICE mit android:exported auf wahr, und einen meta-data-Eintrag, der auf eine XML-Ressource zeigt. Die Berechtigung gehört dem System, sie zu verlangen heißt also, dass sich nur das Betriebssystem an den Dienst binden kann. Die Anwendung hält außerdem die NFC-Berechtigung.
Die XML-Datei ist der Ort, an dem die Kennungen leben. Ihr Wurzelelement host-apdu-service trägt eine für die Nutzenden gedachte Beschreibung und wahlweise requireDeviceUnlock. Es enthält ein oder mehrere Elemente aid-group, jedes mit einer eigenen Beschreibung, einer Kategorie und einem oder mehreren Elementen aid-filter, die je eine einzelne Kennung tragen, hexadezimal geschrieben mit einer geraden Zahl von Zeichen.
Ein Dienst, der aus einem sicheren Element statt aus Ihrem Code antwortet, deklariert sich genauso, mit der Aktion für den Weg außerhalb des Hosts und einem Wurzelelement offhost-apdu-service. Android hat keine Schnittstelle, um unmittelbar mit einem sicheren Element zu sprechen, was die Seite zum sicheren Element einordnet.
Gruppen von Kennungen und Kategorien
Eine Anwendungskennung ist bis zu sechzehn Bytes lang, und das Lesegerät benennt sie in einem Befehl SELECT. Der Leitfaden empfiehlt, eine eigene nach ISO/IEC 7816-5 eintragen zu lassen, wenn Sie eigene Lesegeräte ausrollen, damit sie mit niemandem zusammenstößt. Kennungen, die zusammengehören, kommen in eine Gruppe, und Android leitet eine Gruppe als Ganzes: Entweder erreicht jede Kennung darin Ihren Dienst, oder keine.
Jede Gruppe deklariert eine Kategorie, Zahlung oder anderes. Es kann immer nur eine Gruppe für Zahlungen auf dem Gerät eingeschaltet sein, und eine Anwendung, die Zahlungskennungen einträgt, wickelt nur dann einen Vorgang ab, wenn sie ab Android 15 die Rolle der Wallet hält oder im Vordergrund ist und setPreferredService aufgerufen hat. Ein geschlossenes System, das bei einem einzigen Händler nutzbar ist, gehört in die andere Kategorie, wo Gruppen dauerhaft aktiv bleiben können. Welchen Dienst ein Lesegerät wirklich erreicht, ist das Thema der Seite zur Weiterleitung.
Was der Austausch einhalten muss
Halten Sie ihn kurz. Der Leitfaden setzt eine vernünftige Obergrenze bei etwa 1 KB an Daten, austauschbar in etwa 300 ms, und dieses Maß entscheidet, wie lange jemand das Telefon an das Lesegerät halten muss.
Halten Sie ihn in dem, was die Plattform emuliert. Host Card Emulation beantwortet den genormten Austausch von Befehlen; ein Verfahren, dessen Sicherheit unter dieser Schicht sitzt, MIFARE Classic darunter, lässt sich nicht emulieren, wie die Seite zur Host Card Emulation denen erklärt, die den Code nicht schreiben.
Und entscheiden Sie früh, was bei ausgeschaltetem Bildschirm oder gesperrtem Telefon geschieht, denn die Antwort hängt an der Android-Fassung und an einer Einstellung des Geräts und nicht an Ihrem Code allein. Die Seite zum ausgeschalteten Bildschirm nimmt es Fassung für Fassung.
Häufige Fragen
Muss die Anwendung offen sein, damit die Emulation arbeitet?
Nein. Ein Antippen startet den Dienst, wenn er nicht schon läuft, und der Austausch geschieht im Hintergrund, ohne einen Bildschirm von Ihnen.
Kann Host Card Emulation eine MIFARE-Classic-Karte emulieren?
Nein. Android emuliert ISO-DEP und verarbeitet Befehle der ISO/IEC 7816-4, und Verfahren, deren Sicherheit unter dieser Schicht sitzt, sind außer Reichweite.
Warum wird processCommandApdu im Hauptthread aufgerufen?
Weil das Lesegerät auf eine Antwort wartet. Geben Sie null zurück, wenn die Antwort Arbeit kostet, und senden Sie sie dann mit sendResponseApdu aus einem anderen Thread.
Was bedeutet onDeactivated?
Entweder hat das Lesegerät eine Kennung ausgewählt, die zu einem anderen Dienst führt, oder die Funkverbindung ist abgerissen. Das Argument sagt, welches von beidem.