Uwierzytelnianie odcisku palca wykorzystuje czujnik dotyku wbudowany w wiele urządzeń z systemem Android do identyfikacji użytkownika i zapewnienia dostępu zarówno do urządzenia, jak i funkcjonalności aplikacji, takich jak opcje płatności w aplikacji. Wdrożenie uwierzytelniania odciskiem palca jest wieloetapowym procesem, który może, na początku, wydawać się przytłaczający. Jednak po rozbiciu na poszczególne etapy, proces ten staje się znacznie mniej skomplikowany. W podstawowych kategoriach, uwierzytelnianie odcisków palców jest przede wszystkim kwestią szyfrowania obejmującego klucz, szyfr do wykonywania szyfrowania i menedżera odcisków palców do obsługi procesu uwierzytelniania.
Ten rozdział zapewnia zarówno przegląd uwierzytelniania odcisków palców, jak i szczegółowy, krok po kroku samouczek, który demonstruje praktyczne podejście do implementacji.
Przegląd uwierzytelniania odcisków palców
Istnieje zasadniczo 10 kroków do wdrożenia uwierzytelniania odcisków palców w aplikacji na Androida. Kroki te można podsumować w następujący sposób:
1. Zażądaj pozwolenia na uwierzytelnianie odcisków palców w pliku manifestu projektu.
2. Sprawdź, czy ekran blokady urządzenia, na którym działa aplikacja, jest chroniony kodem PIN, wzorem lub hasłem (odciski palców można rejestrować tylko na urządzeniach, na których ekran blokady został zabezpieczony).
3. Sprawdź, czy na urządzeniu zarejestrowano co najmniej jeden odcisk palca.
4. Utwórz instancję klasy FingerprintManager.
5. Użyj instancji Keystore, aby uzyskać dostęp do kontenera Android Keystore. Jest to miejsce przechowywania używane do bezpiecznego przechowywania kluczy kryptograficznych na urządzeniach z systemem Android.
6. Wygeneruj klucz szyfrujący przy użyciu klasy KeyGenerator i przechowuj go w kontenerze Keystore.
7. Zainicjuj instancję klasy Cipher przy użyciu klucza wygenerowanego w kroku 5.
8. Użyj instancji Cipher do utworzenia CryptoObject i przypisz go do instancji FingerprintManager utworzonej w kroku 4.
9. Wywołaj metodę authenticate instancji FingerprintManager.
10. Zaimplementuj metody do obsługi wywołań zwrotnych wyzwalanych przez proces uwierzytelniania. Zapewnij dostęp do chronionej zawartości lub funkcjonalności po zakończeniu udanego uwierzytelniania.
Każdy z powyższych kroków zostanie omówiony bardziej szczegółowo w samouczku przedstawionym w pozostałej części tego rozdziału.
Creating the Fingerprint Authentication Project
Zacznij ten przykład, uruchamiając środowisko Android Studio i tworząc nowy projekt, wpisując FingerprintDemo w polu Application name i ebookfrenzy.com jako ustawienie Company Domain przed kliknięciem przycisku Next.
Na ekranie form factors, włącz opcję Phone and Tablet i ustaw minimalne ustawienie SDK na API 23: Android 6.0 (Marshmallow). Kontynuuj przez ekrany ustawień, żądając utworzenia pustej aktywności o nazwie FingerprintDemoActivity z odpowiednim układem o nazwie activity_fingerprint_demo.
Konfigurowanie uwierzytelniania odciskiem palca urządzenia
Uwierzytelnianie odciskiem palca jest dostępne tylko na urządzeniach zawierających czujnik dotyku i na których podjęto odpowiednie kroki konfiguracyjne w celu zabezpieczenia urządzenia i zarejestrowania co najmniej jednego odcisku palca. Aby zapoznać się z krokami dotyczącymi konfiguracji sesji emulatora w celu przetestowania uwierzytelniania za pomocą odcisku palca, zapoznaj się z rozdziałem zatytułowanym Using and Configuring the Android Studio 2 AVD Emulator.
Aby skonfigurować uwierzytelnianie za pomocą odcisku palca na urządzeniu fizycznym, zacznij od otwarcia aplikacji Ustawienia i wybrania opcji Zabezpieczenia. Na ekranie ustawień zabezpieczeń należy wybrać opcję Odcisk palca. Na wyświetlonym ekranie z informacjami kliknij przycisk Kontynuuj, aby przejść do ekranu konfiguracji odcisku palca. Zanim będzie można włączyć zabezpieczenie odciskiem palca, należy skonfigurować zapasową metodę odblokowywania ekranu (np. numer PIN). Kliknij przycisk Set Up Screen Lock (Ustaw blokadę ekranu), jeśli ekran blokady nie jest jeszcze zabezpieczony, i wykonaj kroki, aby skonfigurować zabezpieczenie kodem PIN, wzorem lub hasłem.
Po zabezpieczeniu ekranu blokady przejdź do ekranu wykrywania odcisków palców i dotknij czujnika, gdy zostaniesz o to poproszony (Rysunek 62-1), powtarzając proces, aby w razie potrzeby dodać dodatkowe odciski palców.
Rysunek 62-1
Dodanie uprawnienia do odcisków palców do pliku manifestu
Uwierzytelnianie za pomocą odcisków palców wymaga, aby aplikacja zażądała uprawnienia USE_FINGERPRINT w pliku manifestu projektu. W oknie narzędzia Android Studio Project zlokalizuj i edytuj plik app -> manifests -> AndroidManifest.xml, aby dodać żądanie uprawnienia w następujący sposób:
Pobieranie ikony odcisku palca
Google dostarcza standardową ikonę (Rysunek 62-2), która musi być wyświetlana za każdym razem, gdy aplikacja żąda uwierzytelnienia od użytkownika.
Rysunek 62-2
Kopię tej ikony można pobrać z następującego adresu URL:
Otwórz nawigator systemu plików dla swojego systemu operacyjnego, zaznacz nowo pobrany obraz i naciśnij Ctrl-C (Cmd-C w Mac OS X), aby skopiować plik. Wróć do Android Studio, kliknij prawym przyciskiem myszy folder drawable app -> res -> i wybierz opcję menu Paste, aby dodać kopię pliku obrazu do projektu. Gdy pojawi się okno dialogowe Copy, kliknij przycisk OK, aby użyć ustawień domyślnych.
Projektowanie interfejsu użytkownika
W interesie utrzymania przykładu tak prostym, jak to tylko możliwe, jedynymi elementami w interfejsie użytkownika będą TextView i ImageView. Odszukaj i wybierz plik activity_fingerprint_demo.xml, aby załadować go do narzędzia Designer. Po załadowaniu usuń przykładowy obiekt TextView, przeciągnij i upuść obiekt ImageView z panelu i umieść go na środku layoutu.
W panelu Properties zlokalizuj atrybut src, kliknij w odpowiednie pole tekstowe, a następnie przycisk zaznaczony na rysunku 62-3, aby wyświetlić okno dialogowe Resources:
Rysunek 62-3
Z lewego panelu okna dialogowego wybierz opcję Drawable. W panelu głównym wpisz ic_fp w polu wyszukiwania, jak pokazano na Rysunek 62 4, aby zlokalizować ikonę odcisku palca. Wybierz ikonę z okna dialogowego i kliknij przycisk OK, aby przypisać ją do obiektu ImageView.
Rysunek 62-4
Zlokalizuj obiekt Large Text z palety i przeciągnij go tak, aby znalazł się pod obiektem ImageView. Kliknij dwukrotnie obiekt i zmień tekst tak, aby brzmiał „Touch Sensor”. Użyj ikony żarówki, aby wyodrębnić ciąg znaków do zasobu o nazwie touch_sensor.
Po wykonaniu powyższych kroków układ powinien odpowiadać temu pokazanemu na rysunku 62-5:
Rysunek 62-5
Dostęp do usług Keyguard i Fingerprint Manager
Uwierzytelnianie odcisków palców wykorzystuje dwie usługi systemowe w postaci KeyguardManager i FingerprintManager. Edytuj metodę onCreate znajdującą się w pliku FingerprintDemoActivity.java, aby uzyskać referencje do tych dwóch usług w następujący sposób:
package com.ebookfrenzy.fingerprintdemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.app.KeyguardManager;import android.hardware.fingerprint.FingerprintManager;public class FingerprintDemoActivity extends AppCompatActivity { private FingerprintManager fingerprintManager; private KeyguardManager keyguardManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fingerprint_demo); keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); }}
Sprawdzanie ustawień zabezpieczeń
Wcześniej w tym rozdziale podjęto kroki w celu skonfigurowania ekranu blokady i zarejestrowania odcisków palców na urządzeniu lub emulatorze, na którym aplikacja będzie testowana. Ważne jest jednak, aby włączyć kod obronny w aplikacji, aby upewnić się, że te wymagania zostały spełnione przed próbą poszukiwania uwierzytelniania odcisków palców. Te kroki będą wykonywane w metodzie onCreate rezydującej w pliku FingerprintDemoActivity.java, wykorzystując usługi Keyguard i Fingerprint manager. Zauważ, że kod został również dodany w celu sprawdzenia, czy uprawnienie USE_FINGERPRINT zostało skonfigurowane dla aplikacji:
Powyższe zmiany kodu rozpoczynają się od użycia menedżera Keyguard w celu sprawdzenia, czy została skonfigurowana zapasowa metoda odblokowywania ekranu (innymi słowy, kod PIN lub inna metoda uwierzytelniania może być używana jako alternatywa dla uwierzytelniania odcisku palca w celu odblokowania ekranu). W przypadku gdy ekran blokady nie jest zabezpieczony, kod zgłasza problem użytkownikowi i powraca z metody.
Menedżer odcisków palców jest następnie używany do sprawdzenia, czy co najmniej jeden odcisk palca został zarejestrowany na urządzeniu, po raz kolejny zgłaszając problem i powracając z metody w razie potrzeby.
Dostęp do Android Keystore i KeyGenerator
Część procesu uwierzytelniania odcisków palców obejmuje generowanie klucza szyfrowania, który jest następnie bezpiecznie przechowywany na urządzeniu przy użyciu systemu Android Keystore. Zanim klucz może być wygenerowany i przechowywany, aplikacja musi najpierw uzyskać dostęp do Keystore. Nowa metoda o nazwie generateKey zostanie zaimplementowana w pliku FingerprintDemoActivity.java, aby wykonać zadania związane z generowaniem i przechowywaniem klucza. Początkowo, tylko kod dostępu do Keystore zostanie dodany w następujący sposób:
Odniesienie do Keystore jest uzyskiwane poprzez wywołanie metody getInstance klasy Keystore i przekazanie identyfikatora standardowego kontenera Android keystore („AndroidKeyStore”). Kolejnym krokiem w tutorialu będzie wygenerowanie klucza za pomocą usługi KeyGenerator. Przed wygenerowaniem tego klucza należy dodać kod, który pozwoli uzyskać referencję do instancji KeyGenerator, przekazując jako argumenty typ klucza do wygenerowania oraz nazwę kontenera Keystore, w którym klucz ma zostać zapisany:
Generating the Key
Teraz, gdy mamy już referencję do kontenera Android Keystore oraz instancję KeyGenerator, kolejnym krokiem jest wygenerowanie klucza, który zostanie użyty do utworzenia szyfru w procesie szyfrowania. Pozostając w pliku FingerprintDemoActivity.java, dodajemy nowy kod w następujący sposób:
Powyższe zmiany wymagają pewnego wyjaśnienia. Po zaimportowaniu kilku dodatkowych modułów kod deklaruje zmienną łańcuchową reprezentującą nazwę (w tym przypadku „example_key”), która będzie używana podczas przechowywania klucza w kontenerze Keystore.
Następnie ładowany jest kontener keystore i inicjalizowany KeyGenerator. Ten proces inicjalizacji korzysta z klasy KeyGenParameterSpec.Builder w celu określenia typu generowanego klucza. Obejmuje to odniesienie do nazwy klucza, skonfigurowanie klucza tak, aby mógł być użyty zarówno do szyfrowania jak i deszyfrowania, oraz ustawienie różnych parametrów szyfrowania. Wywołanie metody setUserAuthenticationRequired konfiguruje klucz w taki sposób, że użytkownik musi autoryzować każde użycie klucza za pomocą uwierzytelnienia odciskiem palca. Gdy KeyGenerator został skonfigurowany, jest on następnie używany do generowania klucza poprzez wywołanie metody generateKey instancji.
Inicjalizacja szyfru
Teraz, gdy klucz został wygenerowany, następnym krokiem jest inicjalizacja szyfru, który będzie używany do tworzenia zaszyfrowanej instancji FingerprintManager.CryptoObject. Ten CryptoObject będzie z kolei używany podczas procesu uwierzytelniania odcisków palców. Konfiguracja szyfru polega na uzyskaniu instancji Cipher i zainicjalizowaniu jej kluczem przechowywanym w kontenerze Keystore. Dodaj nową metodę o nazwie cipherInit do pliku FingerprintDemoActivity.java, aby wykonać te zadania:
Metoda getInstance klasy Cipher jest wywoływana w celu uzyskania instancji szyfru, który jest następnie konfigurowany z właściwościami wymaganymi do uwierzytelniania odcisków palców. Wygenerowany wcześniej klucz jest następnie pobierany z kontenera Keystore i używany do inicjalizacji instancji Cipher. Błędy są odpowiednio obsługiwane i zwracany jest wynik true lub false w zależności od powodzenia lub nie procesu inicjalizacji szyfru.
Praca nad metodami generateKey i cipherInit została zakończona. Następnym krokiem jest zmodyfikowanie metody onCreate tak, aby wywoływała te metody i w przypadku udanej inicjalizacji szyfru tworzyła instancję CryptoObject.
Tworzenie instancji CryptoObject
Pozostając w pliku FingerprintDemoActivity.java, zmodyfikuj metodę onCreate, aby wywołać dwie nowo utworzone metody i wygenerować CryptoObject w następujący sposób:
Ostatnim zadaniem w projekcie jest zaimplementowanie nowej klasy do obsługi rzeczywistego uwierzytelniania odcisków palców.
Implementing the Fingerprint Authentication Handler Class
Do tej pory w tym rozdziale większość pracy polegała na przygotowaniu do uwierzytelniania odcisków palców pod względem klucza, szyfru i obiektu crypto. Faktyczne uwierzytelnienie jest wyzwalane przez wywołanie metody authenticate instancji FingerprintManager. To wywołanie metody wywoła jedno z wielu zdarzeń zwrotnych w zależności od powodzenia lub niepowodzenia uwierzytelnienia. Zarówno wywołanie metody authenticate jak i metody obsługi wywołania zwrotnego muszą być zaimplementowane w klasie, która rozszerza klasę FingerprintManager.AuthenticationCallback. Taką klasę należy teraz dodać do projektu.
Nawiguj do wpisu app -> java -> com.ebookfrenzy.fingerprintdemo w oknie narzędzia Android Studio Project i kliknij na nim prawym przyciskiem myszy. Z powstałego menu wybierz opcję New -> Java Class, aby wyświetlić okno dialogowe Create New Class. Nadaj klasie nazwę FingerprintHandler i kliknij przycisk OK, aby utworzyć klasę.
Edytuj plik nowej klasy tak, aby rozszerzała ona FingerprintManager.AuthenticationCallback, zaimportował kilka dodatkowych modułów i zaimplementował metodę konstruktora, która pozwoli na przekazanie kontekstu aplikacji podczas tworzenia instancji klasy (kontekst będzie używany w metodach wywołania zwrotnego, aby powiadomić użytkownika o statusie uwierzytelnienia):
package com.ebookfrenzy.fingerprintdemo;import android.Manifest;import android.content.Context;import android.content.pm.PackageManager;import android.hardware.fingerprint.FingerprintManager;import android.os.CancellationSignal;import android.support.v4.app.ActivityCompat;import android.widget.Toast;public class FingerprintHandler extends FingerprintManager.AuthenticationCallback { private CancellationSignal cancellationSignal; private Context appContext; public FingerprintHandler(Context context) { appContext = context; }}
Następnie należy dodać metodę, która może być wywołana w celu zainicjowania uwierzytelnienia odcisku palca. Po wywołaniu tej metody, trzeba będzie przekazać instancje FingerprintManager i CryptoObject. Nazwij tę metodę startAuth i zaimplementuj ją w pliku FingerprintHandler.java w następujący sposób (zauważ, że kod został również dodany, aby ponownie sprawdzić, czy pozwolenie na odcisk palca zostało przyznane):
Następnie, dodaj metody obsługi wywołania zwrotnego, z których każda jest zaimplementowana w celu wyświetlenia wiadomości toast wskazującej wynik uwierzytelnienia odcisku palca:
Ostatnim zadaniem przed testowaniem projektu jest zmodyfikowanie metody onCreate tak, aby tworzyła nową instancję klasy FingerprintHandler i wywoływała metodę startAuth. Edytuj plik FingerprintDemoActivity.java i zmodyfikuj zakończenie metody onCreate tak, aby brzmiało ono następująco:
Testowanie projektu
Z projektem teraz kompletnym uruchom aplikację na fizycznym urządzeniu Android lub sesji emulatora. Po uruchomieniu, albo dotknąć czujnik linii papilarnych lub użyć rozszerzonego panelu sterowania w emulatorze do symulacji dotyku palca, jak opisano w rozdziale zatytułowanym Korzystanie i konfigurowanie Android Studio 2 AVD Emulator. Zakładając, że zarejestrowany odcisk palca zostanie wykryty, pojawi się komunikat toast wskazujący na pomyślne uwierzytelnienie, jak pokazano na Rysunku 62-6:
Rysunek 62-6
Zatrzymaj działającą aplikację i uruchom ją ponownie, tym razem używając niezarejestrowanego odcisku palca do próby uwierzytelnienia. Tym razem powinien pojawić się komunikat o niepowodzeniu uwierzytelniania.
Podsumowanie
Uwierzytelnianie odciskiem palca w systemie Android jest procesem wieloetapowym, który początkowo może wydawać się skomplikowany. Jednak po rozbiciu na poszczególne kroki, proces ten staje się bardziej przejrzysty. Uwierzytelnianie odcisków palców wymaga użycia kluczy, szyfrów i przechowywania kluczy w połączeniu z funkcjami klasy FingerprintManager. Ten rozdział zawiera wprowadzenie do tych kroków i pracę nad tworzeniem przykładowego projektu aplikacji, który ma na celu pokazanie praktycznej implementacji uwierzytelniania odcisków palców w systemie Android.