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 artykule opisujemy, jak działa HCE (Host-based Card Emulation, HCE) i jak stworzyć aplikację, która emuluje kartę NFC za pomocą tej metody.
Emulacja karty z elementem zabezpieczeń
Jeśli emulacja karty NFC jest udostępniana za pomocą bezpiecznego elementu, karta do emulacji jest udostępniana w bezpiecznym elemencie urządzenia 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 zabezpieczeń. Tę koncepcję przedstawia Ilustracja 1:
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.
Emulacja karty host-based
Gdy karta NFC jest emulowana za pomocą emulacji karty bazującej na hoście, dane są kierowane bezpośrednio do procesora hosta, a nie do bezpiecznego elementu. Rysunek 2 ilustrauje, jak działa emulacja karty hosta:
Obsługiwane karty i protokoły NFC
Standardy NFC obsługują wiele różnych protokołów. Istnieją różne typy kart, które można emulować.
Android 4.4 i nowsze 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ą karty emulujące zgodne ze specyfikacją NFC-Forum ISO-DEP (wg normy ISO/IEC 14443-4) oraz przetwarzającą jednostki 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 na Androidzie opiera się na komponentach Androida Service
(nazywanych 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 dotknięcie urządzenia do czytnika NFC uruchamia odpowiednią usługę (jeśli jeszcze nie jest uruchomiona), a transakcję jest wykonywana 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 emulujesz karty używane w obecnej infrastrukturze czytników NFC, identyfikatory AID, których szukają użytkownicy, są zwykle dobrze znane i rejestrowane publicznie (np. identyfikatory AID używane w sieciach płatniczych takich jak Visa i Mastercard).
Jeśli chcesz wdrożyć nową infrastrukturę czytnika dla 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 AID w grupie AI Android zapewnia:
- Wszystkie identyfikatory AID w grupie są kierowane do tej usługi HCE.
- Żadne identyfikatory AID w grupie nie są kierowane do tej usługi szyfrowania na poziomie urządzenia (np. dlatego, że użytkownik wybrał inną usługę, która również poprosiła o identyfikatory 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ć domyślne ustawienia 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 nowszy obsługuje dwie kategorie:
CATEGORY_PAYMENT
(dotyczy aplikacji płatniczych zgodnych ze standardami branżowymi)CATEGORY_OTHER
(w przypadku wszystkich pozostałych aplikacji HCE)
Wdrażanie 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) { ... } }
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. Punkty APDU to pakiety na poziomie aplikacji wymieniane między czytnikiem NFC a usługą HCE. Protokół na poziomie aplikacji działa w połowie dupleksu: czytnik NFC wysyła polecenie APDU i czeka, aż otrzymasz odpowiedź.
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 od razu obliczyć i zwrócić odpowiedzi APDU, 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ź, gdy skończysz.
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 zostało 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ę czytników, nad którą również masz kontrolę, możesz zdefiniować własny protokół i sekwencję ADU. Spróbuj ograniczyć liczbę punktów APK i rozmiar danych do wymiany: dzięki temu użytkownicy będą musieli trzymać urządzenie przy czytniku 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:
Aby poinformować platformę, że jest to usługa HCE implementująca interfejs
HostApduService
, dodaj do deklaracji usługi filtr intencji dla działaniaSERVICE_INTERFACE
.Aby poinformować platformę, których grup identyfikatorów AID usługa wymaga, dodaj w deklaracji usługi tag
SERVICE_META_DATA
<meta-data>
, który wskazuje na zasób XML z dodatkowymi informacjami o usłudze HCE.Ustaw atrybut
android:exported
natrue
i wymagaj uprawnieniaandroid.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 tym przypadku tylko aplikacje zewnętrzne z uprawnieniemandroid.permission.BIND_NFC_SERVICE
mogą się łączyć z Twoją usługą. Ponieważandroid.permission.BIND_NFC_SERVICE
jest uprawnieniem systemowym, skutecznie wymusza to na tym, że tylko system operacyjny Android może powiązać usługę z usługą.
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. Za pomocą atrybutu requireDeviceUnlock
możesz określić, że urządzenie jest odblokowane przed wywołaniem tej usługi na potrzeby obsługi pakietów APK.
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 przezCATEGORY_PAYMENT
lubCATEGORY_OTHER
. - Zawierają co najmniej 1 tag
<aid-filter>
, z których każdy zawiera pojedynczy identyfikator AID. Podaj identyfikator AID w formacie szesnastkowym i upewnij się, że zawiera on parzystą liczbę znaków.
Twoja 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że być zainstalowanych 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:
- Jeśli wybrana domyślna aplikacja portfela zarejestrowała identyfikator AID, jest ona wywoływana.
- Jeśli domyślna aplikacja portfela nie zarejestrowała identyfikatora AID, wywoływana jest usługa, która zarejestrowała ten identyfikator.
- Jeśli więcej niż 1 usługa zarejestrowała identyfikator AID, Android zapyta użytkownika, którą usługę wywołać.
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()
.
Aplikacje Portfela
Android uznaje usługi HCE, które zadeklarowały grupę AID z kategorią płatności, za aplikacje portfela. Android 15 i nowsze wersje zawierają domyślną rolę aplikacji portfela, którą użytkownik może wybrać, klikając Ustawienia > Aplikacje > Aplikacje domyślne. Określa domyślną aplikację portfela, która ma być wywoływana po dotknięciu terminala płatniczego.
Wymagane komponenty w przypadku aplikacji Portfel
Aby zapewnić użytkownikom bardziej atrakcyjne wrażenia wizualne, aplikacje portfeli HCE muszą wyświetlać baner usługi.
Android 13 lub nowszy
Aby lepiej dopasować domyślną listę opcji 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>
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 moduł NFC, aby nie zezwalał na transakcje NFC, a zamiast tego pasywnie obserwował pętle sondowania.
Filtry pętli ankiety
Możesz zarejestrować filtry pętli odpytywania dla HostApduService
, korzystając z jednej z tych metod:
registerPollingLoopFilterForService()
w przypadku filtrów, które muszą dokładnie pasować do ramki odpytywania.registerPollingLoopPatternFilterForService()
w przypadku filtrów, które pasują do wyrażenia regularnego w ramach ram czasowych ankiety.
Gdy filtr pętli odpytywania pasuje do niestandardowych ramek odpytywania, moduł NFC przekazuje te ramki do odpowiedniego HostApduService
, wywołując metodę processPollingFrames()
. Pozwala to usłudze 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 w pętli odpytywania tylko standardowych ramek, stos NFC kieruje te ramki odpytujące do preferowanej usługi na pierwszym planie, jeśli ta usługa jest na pierwszym planie, lub do domyślnego posiadacza roli portfela w innym przypadku.
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ą dostarczać pomiary za pomocą własnej skali, o ile mieści się ona w zakresie 1 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 zezwoli na przeprowadzanie 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 HostApduService
i OffHostApduService
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.
Zachowanie ekranu wyłączonego i ekranu blokady
Sposób działania usług HCE zależy od wersji Androida zainstalowanej na urządzeniu.
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ą bezpieczną komunikację NFC. Gdy funkcja Zabezpiecz komunikację NFC jest włączona, wszystkie emulatory kart (aplikacje hostujące i zewnętrzne) są niedostępne, gdy ekran urządzenia jest wyłączony. Przy wyłączonym ekranie urządzenia dostępne są aplikacje spoza hosta. Możesz sprawdzić obsługę bezpiecznego NFC, korzystając z isSecureNfcSupported()
.
Na urządzeniach z Androidem 10 lub nowszym funkcje ustawienia true
w trybie android:requireDeviceUnlock
są takie same jak w przypadku urządzeń z Androidem 9 lub starszym, ale tylko wtedy, gdy Bezpieczne komunikację NFC jest wyłączone. Oznacza to, że jeśli Zabezpieczona komunikacja NFC jest włączona, 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.
Również na Androidzie 9 i starszych wersjach usługi HCE mogą działać na ekranie blokady.
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 przeznaczona dla deweloperów, którzy wdrożyli aplikację wykorzystującą bezpieczny element do emulacji karty. Implementacja technologii HCE w Androidzie ma działać równolegle z innymi metodami wdrażania emulacji kart, w tym z zastosowaniem bezpiecznych elementów.
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. Może to być procesor hosta, na którym działają aplikacje na Androida, lub połączony bezpieczny element.
Gdy czytnik NFC wysyła urządzenie PDU z urządzeniem SELECT AID
, kontroler NFC go analizuje i sprawdza, czy identyfikatory AID pasują do któregokolwiek z tych identyfikatorów w 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 ilustruje tę architekturę:
Kontroler NFC zwykle zawiera też domyślną trasę dla urządzeń ADU. Jeśli w tabeli routingu nie ma identyfikatora AID, używana jest trasa domyślna. 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ą bezpiecznych elementów, nie muszą się martwić o konfigurowanie tabeli routingu. Android obsługuje je automatycznie. Android musi tylko wiedzieć, które identyfikatory AID są obsługiwane przez usługi HCE, a które są obsługiwane przez bezpieczny element. Tabela routingu jest konfigurowana automatycznie na podstawie zainstalowanych usług i ustawionych przez użytkownika jako preferowane.
W tej sekcji dowiesz się, jak deklarować identyfikatory AID w aplikacjach korzystających z elementu zabezpieczonego do emulacji karty.
Rejestracja AID bezpiecznego elementu
Aplikacje używające bezpiecznego elementu 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>
Poniżej znajdziesz 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 jest zaangażowany w transakcję i nie może uniemożliwić elementowi zabezpieczeń 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 zabezpieczenia
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 projekcie HCE celowo zostało to rozwiązane. Nie ma znaczenia, skąd pochodzą dane, a jedynie bezpiecznie przesyłaj je do kontrolera NFC i wysyłane 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.
Protokół Nfc-A (ISO/IEC 14443 typu A) antykolizyjny i aktywacja
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 ustawiony co najmniej 6 bit (0x20), co oznacza, że urządzenie obsługuje ISO-DEP. Można też ustawić inne bity w SEL_RES
, co wskazuje na przykład 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 oczekiwać, że te parametry będą ustawione zgodnie z wymaganiami NFC Forum dla dowolnego urządzenia HCE.
W sekcji poniżej znajdziesz więcej informacji na temat poszczególnych bajtów odpowiedzi ATS dostarczonej przez kontroler NFC 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 wymagań ani gwarancji dotyczących szybkości transmisji danych.
- 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 wynosić maksymalnie 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.
- Bajty historyczne: urządzenia HCE mogą zwracać do 15 bajtów historycznych. 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, które sieci płatnicze zrzeszone w EMVCo określiły w swojej specyfikacji „Protokół komunikacji zbliżeniowej”. W szczególności:
- FSCI w T0 musi wynosić 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 godzin.
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.