Omówienie emulacji kart opartych na serwerze

Wiele urządzeń z Androidem, które obsługują funkcję NFC, obsługuje już emulację karty NFC. W większości przypadków karta jest emulowana przez oddzielny układ na urządzeniu, zwany elementem zabezpieczeń. Wiele kart SIM udostępnianych przez operatorów bezprzewodowych również zawiera element zabezpieczeń.

Android 4.4 i nowsze wersje udostępniają dodatkową metodę emulacji karty, która nie wymaga elementu bezpiecznego. Nazywa się ona emulacją karty na hoście. Dzięki temu każda aplikacja na Androida może emulować kartę i komunikować się bezpośrednio z czytnikiem NFC. W tym temacie opisujemy, jak działa emulacja karty hosta (HCE) na Androidzie i jak można tworzyć aplikacje, które emulują kartę NFC za pomocą tej techniki.

Emulacja karty z elementem zabezpieczeń

Gdy emulacja karty NFC jest zapewniana za pomocą elementu zabezpieczeń, karta, która ma być emulowana, jest konfigurowana w elemencie zabezpieczeń na urządzeniu za pomocą aplikacji na Androida. Gdy użytkownik przytrzyma urządzenie nad terminalem NFC, kontroler NFC na urządzeniu przekieruje wszystkie dane z czytnika bezpośrednio do elementu zabezpieczającego. Rysunek 1 przedstawia tę koncepcję:

Schemat pokazujący, jak czytnik NFC korzysta z kontrolera NFC do pobierania informacji z elementu zabezpieczeń
Rysunek 1. Emulacja karty NFC z elementem zabezpieczającym.

Bezpieczny element sam nawiązuje połączenie z terminalem NFC, a transakcja nie wymaga udziału żadnej aplikacji na Androida. Po zakończeniu transakcji aplikacja na Androida może bezpośrednio zapytać element zabezpieczeń o stan transakcji i powiadomić użytkownika.

host card emulation

Gdy karta NFC jest emulowana za pomocą emulacji karty na hoście, dane są kierowane bezpośrednio do procesora hosta, a nie do elementu bezpiecznego. Rysunek 2 ilustrauje, jak działa emulacja karty hosta:

Schemat pokazujący, jak czytnik NFC pobiera informacje z procesora za pomocą kontrolera NFC
Rysunek 2. Emulacja karty NFC bez elementu zabezpieczeń.

Obsługiwane karty i protokoły NFC

Diagram przedstawiający zestaw protokołów HCE
Rysunek 3. Stos protokołów HCE w Androidzie.

Standardy NFC obsługują wiele różnych protokołów, a dodatkowo możesz emulować różne typy kart.

Android 4.4 i nowsze wersje obsługują kilka protokołów, które są obecnie powszechnie stosowanych na rynku. Wiele istniejących kart zbliżeniowych jest już opartych na tych protokołach, na przykład karty płatnicze zbliżeniowe. Te protokoły są też obsługiwane przez wiele czytników NFC dostępnych obecnie na rynku, w tym urządzenia z Androidem NFC działające jako czytniki (patrz klasa IsoDep). Umożliwia to tworzenie i wdrażanie kompleksowych rozwiązań NFC w ramach HCE przy użyciu wyłącznie urządzeń z Androidem.

W szczególności Android 4.4 i nowsze obsługują emulację kart opartą na specyfikacji ISO-DEP NFC-Forum (opracowanej na podstawie specyfikacji ISO/IEC 14443-4) oraz przetwarzanie jednostek danych protokołu aplikacji (APDU) zgodnie ze specyfikacją ISO/IEC 7816-4. Android wymaga emulacji ISO-DEP tylko w ramach technologii Nfc-A (ISO/IEC 14443-3 typu A). Obsługa technologii Nfc-B (ISO/IEC 14443-4 Type B) jest opcjonalna. Rysunek 3 przedstawia nakładanie się wszystkich tych specyfikacji.

Usługi HCE

Architektura HCE w Androidzie opiera się na komponentach Service (zwanych usługami HCE). Jedną z kluczowych zalet usługi jest to, że może ona działać w tle bez interfejsu użytkownika. Jest to naturalne rozwiązanie w przypadku wielu aplikacji HCE, takich jak karty lojalnościowe czy karty transportu publicznego, których użytkownik nie musi uruchamiać, aby z nich korzystać. Zamiast tego, gdy przyłożysz urządzenie do czytnika NFC, uruchomi się odpowiednia usługa (jeśli nie była jeszcze uruchomiona) i wykonuje transakcję w tle. Oczywiście możesz w odpowiednich przypadkach uruchamiać dodatkowe interfejsy użytkownika (np. powiadomienia dla użytkowników) z Twojej usługi.

Wybór usługi

Gdy użytkownik przyłoży urządzenie do czytnika NFC, system Android musi wiedzieć, z którą usługą HCE czytnik NFC chce się komunikować. Specyfikacja ISO/IEC 7816-4 określa sposób wybierania aplikacji, który koncentruje się na identyfikatorze aplikacji (AID). AID składa się z maksymalnie 16 bajtów. Jeśli chcesz emulować karty dla istniejącej infrastruktury czytników NFC, identyfikatory AID, których szukają te czytniki, są zwykle dobrze znane i publicznie zarejestrowane (np. identyfikatory AID sieci płatniczych takich jak Visa czy MasterCard).

Jeśli chcesz wdrożyć nową infrastrukturę czytnika w swojej aplikacji, musisz zarejestrować własne identyfikatory AID. Procedura rejestracji identyfikatorów AID jest określona w specyfikacji ISO/IEC 7816-5. Jeśli wdrażasz na Androida aplikację HCE, zalecamy zarejestrowanie identyfikatora AID zgodnie z normą 7816-5, ponieważ zapobiega to kolizjom z innymi aplikacjami.

Grupy identyfikatorów AID

W niektórych przypadkach usługa HCE może wymagać rejestracji wielu identyfikatorów AID i ustawienia ich jako domyślnych dla wszystkich identyfikatorów AID w celu wdrożenia określonej aplikacji. Niektóre identyfikatory AID w grupie, które są przekazywane do innej usługi, nie są obsługiwane.

Lista identyfikatorów AID przechowywanych razem jest nazywana grupą identyfikatorów AID. W przypadku wszystkich identyfikatorów AID w grupie identyfikatorów AID Android gwarantuje co najmniej 1 z tych działań:

  • Wszystkie identyfikatory AID w grupie są kierowane do tej usługi HCE.
  • Żadne identyfikatory AID w grupie nie są kierowane do tej usługi HCE (np. dlatego, że użytkownik wybrał inną usługę, która również wysłała żądanie co najmniej jednego identyfikatora AID w grupie).

Innymi słowy, nie ma stanu pośredniego, w którym niektóre identyfikatory AID w grupie mogą być kierowane do jednej usługi HCE, a niektóre do innej.

Grupy i kategorie identyfikatorów AID

Każdą grupę identyfikatorów AID możesz powiązać z kategorią. Dzięki temu Android może grupować usługi HCE według kategorii, co z kolei pozwala użytkownikowi ustawić ustawienia domyślne na poziomie kategorii zamiast na poziomie identyfikatora AID. Unikaj wspominania identyfikatorów AID w częściach aplikacji przeznaczonych dla użytkowników, ponieważ nie mają one żadnego znaczenia dla przeciętnego użytkownika.

Android 4.4 i nowsze wersje obsługują 2 kategorie:

Wdrożenie usługi host card emulation

Aby emulować kartę NFC za pomocą emulacji karty hosta, musisz utworzyć komponent Service, który będzie obsługiwał transakcje NFC.

Sprawdzanie obsługi HCE

Aplikacja może sprawdzić, czy urządzenie obsługuje HCE, sprawdzając, czy jest włączona funkcja FEATURE_NFC_HOST_CARD_EMULATION. Użyj tagu <uses-feature> w pliku manifestu aplikacji, aby zadeklarować, że aplikacja korzysta z funkcji HCE i czy jest ona wymagana do jej działania.

Wdrożenie usługi

Android 4.4 i nowsze wersje udostępniają wygodną klasę Service, której można użyć jako podstawy do implementacji usługi HCE: klasa HostApduService.

Pierwszym krokiem jest rozszerzenie HostApduService, jak pokazano w tym przykładzie kodu:

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) {
       ...
    }
}

Interfejs HostApduService deklaruje 2 abstrakcyjne metody, które musisz zastąpić i zaimplementować. Jeden z nich, processCommandApdu(), jest wywoływany za każdym razem, gdy czytnik NFC wysyła do usługi jednostkę danych protokołu aplikacji (APDU). APDU są zdefiniowane w specyfikacji ISO/IEC 7816-4. APDU to pakiety na poziomie aplikacji wymieniane między czytnikiem NFC a Twoją usługą HCE. Ten protokół na poziomie aplikacji działa w trybie półdupleksowym: czytnik NFC wysyła polecenie APDU i czeka na odpowiedź APDU.

Jak już wspomnieliśmy, Android używa identyfikatora AID, aby określić, z którą usługą HCE czytnik chce się komunikować. Zazwyczaj pierwszy APDU wysyłany przez czytnik NFC na urządzenie jest APDU SELECT AID. Zawiera on identyfikator AID, z którym czytnik chce się komunikować. Android wyodrębnia AID z APDU, przekształca go w usługę HCE, a następnie przekazuje APDU do zwróconej usługi.

Odpowiedź APDU możesz wysłać, zwracając bajty odpowiedzi APDU z processCommandApdu(). Pamiętaj, że ta metoda jest wywoływana w głównym wątku aplikacji, którego nie należy blokować. Jeśli nie możesz obliczyć i zwrócić odpowiedzi APDU od razu, zwracaj null. Następnie możesz wykonać niezbędne czynności w innym wątku i użyć metody sendResponseApdu() zdefiniowanej w klasie HostApduService, aby wysłać odpowiedź.

Android będzie przekierowywać nowe APDU z czytnika do usługi, dopóki nie nastąpi jedno z tych zdarzeń:

  • Czytnik NFC wysyła kolejny pakiet APDU SELECT AID, który system operacyjny przekształca w inną usługę.
  • Połączenie NFC między czytnikiem NFC a urządzeniem jest zerwane.

W obu przypadkach implementacja klasy onDeactivated() jest wywoływana z argumentem wskazującym, które z tych zdarzeń miało miejsce.

Jeśli korzystasz z obecnej infrastruktury czytników, musisz zaimplementować istniejący protokół na poziomie aplikacji, którego oczekują czytniki w usłudze HCE.

Jeśli wdrażasz nową infrastrukturę czytnika, którą również kontrolujesz, możesz zdefiniować własny protokół i sekwencję APDU. Spróbuj ograniczyć liczbę APDU i rozmiar danych do wymiany: dzięki temu użytkownicy będą musieli trzymać urządzenie nad czytnikiem NFC tylko przez krótki czas. Rozsądny górny limit to około 1 KB danych, które można zwykle przesłać w ciągu 300 ms.

Deklaracja w pliku manifestu usługi i rejestracja AID

W pliku manifestu musisz zadeklarować usługę, jak zwykle, ale musisz też dodać do deklaracji usługi kilka dodatkowych elementów:

  1. Aby poinformować platformę, że jest to usługa HCE implementująca interfejs HostApduService, dodaj do deklaracji usługi filtr intencji dla działania SERVICE_INTERFACE.

  2. Aby poinformować platformę, których grup identyfikatorów AID usługa prosi o utworzenie, dodaj w deklaracji usługi tag SERVICE_META_DATA <meta-data> wskazujący na zasób XML z dodatkowymi informacjami o usłudze HCE.

  3. Ustaw atrybut android:exported na true i wymagaj uprawnienia android.permission.BIND_NFC_SERVICE w deklaracji usługi. Pierwsza z nich zapewnia, że usługa może być powiązana z aplikacją zewnętrzną. W drugim przypadku tylko aplikacje zewnętrzne z uprawnieniem android.permission.BIND_NFC_SERVICE mogą się łączyć z Twoją usługą. Uprawnienie android.permission.BIND_NFC_SERVICE jest uprawnieniem systemowym, co oznacza, że tylko system operacyjny Android może się z nim powiązać.

Oto przykład deklaracji w pliku manifestu 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>

Ten tag metadanych wskazuje plik apduservice.xml. Poniżej przedstawiamy przykład takiego pliku z deklaracją jednej grupy AID zawierającej 2 własne identyfikatory 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>

Tag <host-apdu-service> musi zawierać atrybut <android:description>, który zawiera czytelny dla użytkownika opis usługi, który możesz wyświetlić w interfejsie aplikacji. Możesz użyć atrybutu requireDeviceUnlock, aby określić, że urządzenie jest odblokowane, zanim wywołasz tę usługę do obsługi APDU.

Tag <host-apdu-service> musi zawierać co najmniej 1 tag <aid-group>. Każdy tag <aid-group> jest wymagany do:

  • Zawierać atrybut android:description zawierający przyjazny dla użytkownika opis grupy AID, który można wyświetlić w interfejsie.
  • Atrybut android:category musi być ustawiony tak, aby wskazywać kategorię, do której należy grupa AID, np. stałe ciągu znaków zdefiniowane przez CATEGORY_PAYMENT lub CATEGORY_OTHER.
  • Zawierać co najmniej 1 tag <aid-filter>, z którego każdy zawiera 1 identyfikator AID. Podaj identyfikator AID w formacie szesnastkowym i upewnij się, że zawiera on parzystą liczbę znaków.

Aplikacja musi też mieć uprawnienie NFC, aby zarejestrować się jako usługa HCE.

Rozwiązywanie konfliktów dotyczących AID

Na jednym urządzeniu można zainstalować wiele komponentów HostApduService, a ten sam identyfikator AID może być zarejestrowany przez więcej niż 1 usługę. Android określa, którą usługę wywołać, wykonując te czynności:

  1. Jeśli wybrana przez użytkownika domyślna aplikacja portfela zarejestrowała identyfikator AID, jest ona wywoływana.
  2. Jeśli domyślna aplikacja portfela nie zarejestrowała identyfikatora AID, wywoływana jest usługa, która zarejestrowała ten identyfikator.
  3. Jeśli więcej niż 1 usługa zarejestrowała identyfikator AID, Android pyta użytkownika, którą usługę wywołać.

Ustawienie usługi działającej na pierwszym planie

Aplikacje na pierwszym planie mogą wywoływać setPreferredService, aby określić, która usługa emulacji kart ma być preferowana, gdy na pierwszym planie jest określona aktywność. To ustawienie aplikacji na pierwszym planie zastępuje rozwiązanie konfliktu dotyczące AID. Jest to zalecana praktyka, gdy aplikacja przewiduje, że użytkownik może użyć emulacji karty NFC.

Android 13 lub nowszy

Aby lepiej dopasować domyślną listę dostępnych płatności w interfejsie Ustawienia, zmień wymagania dotyczące banera na ikonę kwadratu. Najlepiej, gdyby była identyczna z ikoną w aplikacjach. Ta zmiana powoduje większą spójność i czystszy wygląd.

Android 12 i starsze

Ustaw rozmiar banera usługi na 260 x 96 dp, a następnie ustaw rozmiar banera usługi w pliku XML z metadanymi, dodając atrybut android:apduServiceBanner do tagu <host-apdu-service>, który wskazuje na zasób rysowalny. Oto przykład:

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

Aplikacje Portfela

Android 15 i nowsze wersje zawierają domyślną rolę aplikacji portfela, którą użytkownik może wybrać, klikając Ustawienia > Aplikacje > Domyślne aplikacje. Określa domyślną aplikację portfela, która ma się uruchamiać po użyciu terminala płatniczego. Android uznaje usługi HCE, które zadeklarowały grupę AID z kategorią płatności, za aplikacje portfela.

Sprawdź, czy Twoja aplikacja jest domyślną aplikacją portmonetki

Aplikacje mogą sprawdzić, czy są domyślną aplikacją portfela, przekazując wartość RoleManager.ROLE_WALLET do RoleManager.isRoleHeld().

Jeśli Twoja aplikacja nie jest domyślna, możesz poprosić o rolę domyślnego portfela cyfrowego, przekazując wartość RoleManager.ROLE_WALLET do RoleManager.createRequestRoleIntent().

Wymagane komponenty w przypadku aplikacji Portfel

Aby zapewnić użytkownikom bardziej atrakcyjne wrażenia wizualne, aplikacje portfeli HCE muszą wyświetlać baner usługi.

Tryb obserwacji

Android 15 wprowadza funkcję Tryb obserwacji. Gdy tryb obserwacji jest włączony, urządzenie może obserwować pętle sondowania NFC i wysyłać powiadomienia o nich do odpowiednich komponentów HostApduService, aby mogły się one przygotować do interakcji z danym terminalem NFC. HostApduService może uruchomić tryb obserwacji, przekazując wartość true do setObserveModeEnabled(). To polecenie instruuje stos NFC, aby nie zezwalał na transakcje NFC, a zamiast tego pasywnie obserwował pętle sondowania.

Filtry pętli ankiety

Filtry pętli zapytań możesz zarejestrować dla HostApduService, korzystając z jednej z tych metod:

Gdy filtr pętli odpytywania pasuje do niestandardowych ramek odpytywania, moduł NFC przekazuje te ramki do odpowiedniego HostApduService, wywołując metodę processPollingFrames(). Dzięki temu usługa może podjąć wszelkie niezbędne kroki, aby upewnić się, że użytkownik jest gotowy do dokonania transakcji i zamierza to zrobić, np. uwierzytelnić użytkownika. Jeśli czytnik NFC używa tylko standardowych ramek w pętli sondowania, pakiet NFC kieruje te ramki sondowania do preferowanej usługi na pierwszym planie, jeśli taka usługa jest na pierwszym planie, lub do domyślnego uchwytu roli portfela w innych przypadkach.

Powiadomienia o ramce odpytywania zawierają też pomiar siły pola specyficzny dla dostawcy, który możesz pobrać, wywołując funkcję getVendorSpecificGain(). Dostawcy mogą podawać pomiary według własnej skali, o ile mieści się ona w ramach pojedynczego bajta.

Odpowiedź na pętle zapytań i wyjście z trybu obserwacji

Gdy usługa będzie gotowa do przeprowadzenia transakcji, może wyjść z trybu obserwacji, przekazując false do setObserveModeEnabled(). W tym celu stos NFC umożliwi przeprowadzenie transakcji.

Komponenty HostApduService mogą wskazywać, że tryb obserwacji powinien być włączony, gdy są preferowaną usługą płatności, przez ustawienie shouldDefaultToObserveMode na true w pliku manifestu lub wywołanie CardEmulation.setShouldDefaultToObserveModeForService().

Komponenty HostApduServiceOffHostApduService mogą też wskazywać, że filtry pętli pollingu, które pasują do otrzymanych ramek pętli pollingu, powinny automatycznie wyłączać tryb obserwacji i umożliwiać przeprowadzanie transakcji przez ustawienie wartości autoTransact na true w deklaracji PollingLoopFilter w pliku manifestu.

Ustawienie usługi działającej na pierwszym planie

Aplikacje na pierwszym planie mogą wywoływać setPreferredService, aby określić, która usługa emulacji kart ma być preferowana, gdy na pierwszym planie jest określona aktywność. To ustawienie aplikacji na pierwszym planie zastępuje stan trybu obserwacji urządzenia odpowiadający wartości shouldDefaultToObserveMode dla danej usługi. Wartość tę można ustawić na jeden z tych sposobów:

Wyłączanie ekranu i zachowanie ekranu blokady

Zachowanie usług HCE różni się w zależności od wersji Androida zainstalowanej na urządzeniu.

Android 15 lub nowszy

Jeśli domyślna aplikacja portfela włączy tryb obserwacji na urządzeniu, które go obsługuje, aplikacja ta zastąpi działanie funkcji odblokowywania i wyłączania ekranu, ponieważ kontroluje, kiedy transakcja może zostać przeprowadzona. Niektóre aplikacje Portfel mogą wymagać odblokowania urządzenia przed przeprowadzeniem transakcji, jeśli tryb obserwacji nie wykryje rozpoznawalnego wzorku ankiety.

Zachęcamy deweloperów do pracy z urządzeniami czytnikowymi, aby emitować rozpoznawalne wzorce pętli odpytywania i rejestrować się w celu obsługi tych wzorów w aplikacji.

Android 12 lub nowszy

W aplikacjach kierowanych na Androida 12 (poziom interfejsu API 31) lub nowszego możesz włączyć płatności NFC bez włączania ekranu urządzenia, ustawiając wartośćrequireDeviceScreenOn nafalse.

Android 10 lub nowszy

Urządzenia z Androidem 10 (poziom interfejsu API 29) lub nowszym obsługują bezpieczne NFC. Gdy włączona jest funkcja Zabezpiecz komunikację NFC, wszystkie emulatory kart (aplikacje hosta i aplikacje hosta zewnętrznego) są niedostępne, gdy ekran urządzenia jest wyłączony. Gdy funkcja Zabezpiecz komunikację NFC jest wyłączona, aplikacje hosta zewnętrznego są dostępne, gdy ekran urządzenia jest wyłączony. Obsługę Zabezpiecz komunikację NFC można sprawdzić za pomocą isSecureNfcSupported().

Na urządzeniach z Androidem 10 lub nowszym funkcja ustawienia wartości android:requireDeviceUnlock na true działa tak samo jak na urządzeniach z Androidem 9 lub starszym, ale tylko wtedy, gdy funkcja Bezpieczne NFC jest wyłączona. Oznacza to, że jeśli włączona jest funkcja Bezpieczne NFC, usługi HCE nie mogą działać na ekranie blokady niezależnie od ustawienia android:requireDeviceUnlock.

Android 9 i starsze

Na urządzeniach z Androidem 9 (poziom interfejsu API 28) i starszym kontroler NFC oraz procesor aplikacji są całkowicie wyłączone, gdy ekran urządzenia jest wyłączony. Dlatego usługi HCE nie działają, gdy ekran jest wyłączony.

Usługi HCE mogą działać na ekranie blokady także w Androidzie 9 i starszych. Jest on jednak kontrolowany przez atrybut android:requireDeviceUnlock w tagu <host-apdu-service> usługi HCE. Domyślnie odblokowywanie urządzenia nie jest wymagane, a usługa jest wywoływana nawet wtedy, gdy urządzenie jest zablokowane.

Jeśli dla usługi HCE atrybut android:requireDeviceUnlock ma wartość true, Android prosi użytkownika o odblokowanie urządzenia, gdy:

  • użytkownik dotyka czytnika NFC.
  • czytnik NFC wybiera identyfikator AID, który jest mapowany na Twoją usługę.

Po odblokowaniu Android wyświetla okno z prośbą o ponowne kliknięcie w celu dokończenia transakcji. Jest to konieczne, ponieważ użytkownik może odsunąć urządzenie od czytnika NFC, aby je odblokować.

Współistnienie z kartami z elementem zabezpieczającym

Ta sekcja jest interesująca dla deweloperów, którzy wdrożą aplikację korzystającą z elementu zabezpieczeń do emulacji karty. Implementacja HCE w Androidzie została zaprojektowana tak, aby działać równolegle z innymi metodami implementacji emulacji karty, w tym z użyciem elementów zabezpieczeń.

Ta koegzystencja opiera się na zasadzie zwanej kierowaniem identyfikatora klienta. Kontroler NFC przechowuje tabelę routingu, która zawiera (skończoną) listę reguł routingu. Każda reguła routingu zawiera identyfikator AID i miejsce docelowe. Docelowo może to być procesor hosta, na którym działają aplikacje na Androida, lub połączony element zabezpieczający.

Gdy czytnik NFC wysyła APDU z wartością SELECT AID, kontroler NFC analizuje go i sprawdza, czy identyfikatory AID pasują do dowolnego identyfikatora AID w swojej tabeli routingu. Jeśli się zgadza, ten APDU i wszystkie kolejne APDU są wysyłane do miejsca docelowego powiązanego z AID, dopóki nie zostanie odebrany inny APDU SELECT AID lub połączenie NFC nie zostanie przerwane.

Rysunek 4 przedstawia tę architekturę:

Diagram przedstawiający czytnik NFC komunikujący się z elementem zabezpieczeń i procesorem
Rysunek 4. Android obsługujący zarówno elementy zabezpieczeń, jak i host card emulation.

Kontroler NFC zwykle zawiera też domyślną trasę dla APDU. Jeśli w tabeli routingu nie ma identyfikatora AID, używana jest domyślna trasa. To ustawienie może się różnić w zależności od urządzenia, ale na urządzeniach z Androidem należy je włączyć, aby identyfikatory AID rejestrowane przez aplikację były prawidłowo kierowane do hosta.

Aplikacje na Androida, które implementują usługę HCE lub używają bezpiecznego elementu, nie muszą się martwić konfigurowaniem tabeli routingu. Android robi to automatycznie. Android musi tylko wiedzieć, które identyfikatory AID mogą być obsługiwane przez usługi HCE, a które przez bezpieczny element. Tabela routingu jest konfigurowana automatycznie na podstawie zainstalowanych usług i ustawionych przez użytkownika jako preferowane.

W tej sekcji wyjaśniamy, jak deklarować identyfikatory AID w przypadku aplikacji, które używają bezpiecznego elementu do emulacji karty.

Rejestrowanie identyfikatora AID elementu zabezpieczeń

Aplikacje korzystające z elementu zabezpieczeń do emulacji karty mogą zadeklarować w pliku manifestu usługę poza hostem. Deklaracja takiej usługi jest prawie identyczna z deklaracją usługi HCE. Wyjątki:

  • Działanie używane w filtrze intencji musi być ustawione na SERVICE_INTERFACE.
  • Atrybut nazwy metadanych musi mieć wartość SERVICE_META_DATA.
  • Plik XML z metadanymi musi zawierać tag główny <offhost-apdu-service>.

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

Oto przykład odpowiadającego pliku apduservice.xml z 2 identyfikatorami AID:

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

Atrybut android:requireDeviceUnlock nie dotyczy usług poza hostem, ponieważ procesor hosta nie uczestniczy w transakcji i nie może uniemożliwić bezpiecznemu elementowi wykonywania transakcji, gdy urządzenie jest zablokowane.

Atrybut android:apduServiceBanner jest wymagany w przypadku usług pozahostowych, które są aplikacjami płatniczymi i mogą być wybierane jako domyślne aplikacje płatnicze.

Wywoływanie usługi poza hostem

Android nigdy nie uruchamia ani nie wiąże się z usługą, która jest zadeklarowana jako „off-host”, ponieważ rzeczywiste transakcje są wykonywane przez bezpieczny element, a nie przez usługę Android. Deklaracja usługi umożliwia aplikacjom rejestrowanie identyfikatorów AID obecnych w Bezpiecznym elemencie.

HCE i bezpieczeństwo

Architektura HCE zapewnia jeden podstawowy element zabezpieczeń: ponieważ usługa jest chroniona przez uprawnienie systemowe BIND_NFC_SERVICE, tylko system operacyjny może się z nią łączyć i komunikować. Dzięki temu otrzymane przez Ciebie APDU jest rzeczywiście APDU otrzymanym przez system operacyjny od kontrolera NFC, a wysłane przez Ciebie APDU trafia tylko do systemu operacyjnego, który z kolei przekazuje APDU bezpośrednio do kontrolera NFC.

Ostatnim problemem jest to, skąd aplikacja pobiera dane, które wysyła do czytnika NFC. W ramach projektu HCE jest to celowo odłączone. Nie ma znaczenia, skąd pochodzą dane, ważne jest tylko to, aby były bezpiecznie przesyłane do kontrolera NFC i do czytnika NFC.

Aby bezpiecznie przechowywać i pobierać dane, które chcesz wysłać z usługi HCE, możesz na przykład skorzystać z piaskownicy aplikacji na Androida, która izoluje dane Twojej aplikacji od innych aplikacji. Więcej informacji o bezpieczeństwie w Androidzie znajdziesz w wskazówkach dotyczących bezpieczeństwa.

Parametry i szczegóły protokołu

Ta sekcja jest interesująca dla deweloperów, którzy chcą wiedzieć, których parametrów protokołów używają urządzenia HCE w fazie zapobiegania kolizjom i fazie aktywacji protokołów NFC. Umożliwia to zbudowanie infrastruktury czytnika zgodnej z urządzeniami z Androidem HCE.

Nfc-A (ISO/IEC 14443 typu A) zapobieganie kolizjom i aktywacja protokołu

W ramach aktywacji protokołu Nfc-A wymienianych jest kilka ramek.

W pierwszej części wymiany urządzenie HCE przedstawia swój identyfikator UID. Należy przyjąć, że identyfikator ten jest losowy. Oznacza to, że przy każdym kliknięciu UID wyświetlany czytelnikowi jest losowo generowany. Z tego powodu czytniki NFC nie powinny polegać na identyfikatorze UID urządzeń HCE jako formie uwierzytelniania lub identyfikacji.

Czytnik NFC może następnie wybrać urządzenie HCE, wysyłając polecenie SEL_REQ. Odpowiedź SEL_RES urządzenia HCE ma co najmniej 6 bitów (0x20) ustawionych, co wskazuje, że urządzenie obsługuje ISO-DEP. Pamiętaj, że inne bity w SEL_RES mogą być też ustawione, co wskazuje na przykład na obsługę protokołu NFC-DEP (p2p). Ponieważ inne bity mogą być ustawione, czytniki, które chcą wchodzić w interakcje z urządzeniami HCE, powinny sprawdzać tylko 6. bit, a nie porównywać pełnego SEL_RES z wartością 0x20.

Aktywacja ISO-DEP

Po aktywowaniu protokołu NFC-A czytnik NFC inicjuje aktywację protokołu ISO-DEP. Wysyła ona polecenie RATS (Request for Answer To Select). Kontroler NFC generuje odpowiedź RATS, czyli ATS. Usługi HCE nie mogą konfigurować wartości ATS. Jednak implementacje HCE muszą spełniać wymagania NFC Forum dotyczące odpowiedzi ATS, aby czytniki NFC mogły liczyć na to, że te parametry są ustawione zgodnie z wymaganiami NFC Forum dla dowolnego urządzenia HCE.

W sekcji poniżej znajdziesz więcej informacji o poszczególnych bajtach odpowiedzi ATS, którą kontroler NFC udostępnia na urządzeniu HCE:

  • TL: długość odpowiedzi systemu ATS. Nie może wskazywać długości większej niż 20 bajtów.
  • T0: na wszystkich urządzeniach HCE bity 5, 6 i 7 muszą być ustawione, co oznacza, że w odpowiedzi ATS są uwzględnione wartości TA(1), TB(1) i TC(1). Bity 1–4 wskazują FSCI, kodujący maksymalny rozmiar ramki. Na urządzeniach HCE wartość FSCI musi mieścić się w zakresie od 0 do 8 godzin.
  • T(A)1: definiuje bitrate między czytnikiem a emulatorem oraz określa, czy mogą być asymetryczne. W przypadku urządzeń HCE nie ma żadnych wymagań dotyczących szybkości transmisji danych ani gwarancji.
  • T(B)1: bity 1–4 wskazują czas rozpoczęcia ochrony ramki (SFGI). W przypadku urządzeń z funkcją HCE czas trwania sesji SFGI musi być krótszy niż 8 godzin. Bity 5–8 wskazują liczbę całkowitą czasu oczekiwania na ramkę (FWI) i kodują czas oczekiwania na ramkę (FWT). W przypadku urządzeń HCE czas FWI musi wynosić maksymalnie 8 godzin.
  • T(C)1: bit 5 wskazuje obsługę „zaawansowanych funkcji protokołu”. Urządzenia HCE mogą obsługiwać „zaawansowane funkcje protokołu”, ale nie muszą. Bit 2 wskazuje obsługę DID. Urządzenia HCE mogą obsługiwać DID, ale nie muszą. Bit 1 wskazuje obsługę NAD. Urządzenia HCE nie mogą obsługiwać NAD i ustawić bit 1 na 0.
  • Historyczne bajty: urządzenia HCE mogą zwracać maksymalnie 15 historycznych bajtów. Czytniki NFC, które chcą wchodzić w interakcję z usługami HCE, nie powinny zakładać niczego na temat zawartości ani obecności bajtów historycznych.

Pamiętaj, że wiele urządzeń HCE jest zgodnych z wymaganiami protokołów określonych przez EMVCo w specyfikacji „Protokół komunikacji zbliżeniowej”. W szczególności:

  • Wartość FSCI w T0 musi mieścić się w zakresie od 2 do 8 godzin.
  • T(A)1 musi mieć wartość 0x80, co oznacza, że obsługiwana jest tylko szybkość transmisji 106 kb/s, a asymetryczne szybkości transmisji między czytnikiem a emulatorem nie są obsługiwane.
  • FWI w T(B)1 musi wynosić mniej niż 7 h.

Wymiana danych APDU

Jak już wspomnieliśmy, implementacje HCE obsługują tylko jeden kanał logiczny. Wybieranie aplikacji na różnych kanałach logicznych nie działa na urządzeniu HCE.