Aplicația de amprentă Android atașați autentificarea cu amprentă digitală

Android API pentru amprentele digitale: atașați autentificarea cu amprentă digitală +19

  • 20.12.16 08:14 •
  • nullpex •
  • # 317706
  • Habrahabr •
  • Tutorial •
  • 0 •
  • 4600

- la fel ca Forbes, doar mai bine.

Bună, Habr! A fost nevoie de destul de mult timp, cum a făcut cu amprentă digitală API pentru Android, pe rețea multe mostre de cod disparate cu privire la implementarea și utilizarea acestuia, dar Habré, pentru un motiv sau altul, acest subiect a lua rundă. După părerea mea, este timpul să corectăm această neînțelegere. Toți sunt interesați să ceară o pisică.

Aplicația de amprentă Android atașați autentificarea cu amprentă digitală


Cel mai scurt program educațional


Deci, ce este API-ul Fingerprint? API permite utilizatorului să se autentifice cu amprenta sa, evident. Pentru a lucra cu senzorul, API ne oferă FingerprintManager. destul de ușor să învețe.

Cum se utilizează? Dar acest lucru este mai interesant. Aproape oriunde este necesară autentificarea parolei, este posibil să se securizeze autentificarea prin amprentă digitală. Imaginați-vă o aplicație constând din LoginActivity și MainActivity. La pornire, ajungem la ecranul de conectare, introduceți codul PIN, accesați datele. Dar dorim să înlocuim intrarea cu codul PIN la intrare prin amprentă digitală. Apropo, nu obținem un înlocuitor pe deplin, putem salva numai utilizatorul de la introducerea manuală a unui cod PIN, înlocuind codul PIN memorat anterior (adică aplicația client-server în care doriți să trimiteți serverul de parolă).

Unde este senzorul?


Pentru a începe să obțineți profit din noul API, primul pas este să adăugați permisiunea în manifest:


Desigur, puteți utiliza API-ul Fingerprint numai pe dispozitive care îl acceptă: în consecință, acestea sunt dispozitive Android 6+ cu senzor.

Compatibilitatea poate fi ușor verificată utilizând metoda:


FingerprintManagerCompat este un wrapper convenabil pentru FingerprintManager obișnuit. care simplifică verificarea compatibilității dispozitivului, încapsulând verificarea versiunii API. În acest caz, isHardwareDetected () returnează false. dacă API este sub 23.

Apoi, trebuie să înțelegem dacă senzorul este gata de utilizare. Pentru a face acest lucru, definim enum states:


Și să folosim această metodă:


Codul este suficient de banal. O mică neînțelegere poate provoca un moment când verificăm dacă dispozitivul este blocat. Avem nevoie de acest test, deoarece, deși Android nu permite adăugarea amprentelor digitale la un dispozitiv neprotejat, unii producători îl ocolește, deci nu va face rău pentru a fi sigur.

Stări diferite pot fi folosite pentru a da utilizatorului posibilitatea de a înțelege ce se întâmplă și de al îndruma pe calea adevărată.

Pregătirea


Așadar, fără a ne concentra asupra verificării valabilității codului PIN, vom estima următoarea logică simplificată a acțiunilor:

  • Utilizatorul introduce un cod PIN dacă SensorState.READY. apoi salvăm codul PIN, executați MainActivity.
  • Reporniți aplicația dacă SensorState.READY. apoi citiți amprenta, obțineți codul PIN, simulați intrarea, executați MainActivity.

Schema ar fi suficient de simplă, dacă nu de un singur lucru: Google recomandă cu tărie să nu păstrați datele private ale utilizatorilor în mod clar. Prin urmare, avem nevoie de un mecanism de criptare și decriptare pentru, respectiv, conservare și utilizare. Vom face asta.

Ce avem nevoie pentru a cripta și a decripta:

  1. Tastatură protejată.
  2. Cheia criptografică.
  3. Cod cifrat


Pentru a lucra cu amprentele, sistemul ne oferă propriul magazin de chei - "AndroidKeyStore" și garantează protecția împotriva accesului neautorizat. Vom folosi:


Este necesar să acceptați, să înțelegeți și să iertați că magazinul de chei stochează numai cheile criptografice. Parolele, codurile PIN și alte date private nu pot fi stocate acolo.


Avem două opțiuni pentru chei: o cheie simetrică și o pereche de chei publice și private. Din considerentele lui UX, folosim o pereche. Acest lucru ne va permite să separăm intrarea imprimării de criptarea codului PIN.

Vom primi cheile de la magazinul de chei, dar mai întâi trebuie să le punem acolo. Pentru a crea o cheie, utilizați generatorul.


Atunci când inițializăm, specificăm ce tastă vor fi cheile generate și la care algoritmul este destinat cheii.

Aceeași generație are loc după cum urmează:


Aici trebuie să fii atenți la două locuri:

  • KEY_ALIAS este pseudonimul cheii, prin care îl vom scoate din chestor, de la PSF-urile obișnuite.
  • .setUserAuthenticationRequired (adevărat) - acest steag indică faptul că de fiecare dată când trebuie să folosim cheia, va trebui să ne confirmăm, în cazul nostru, folosind o amprentă digitală.

Verificați prezența cheii după cum urmează:

Cod cifrat


Criptarea și decriptarea în Java este gestionată de obiectul Cipher.


Argumentul ad-hoc al argumentului este șirul transformării, care include algoritmul. modul de amestecare și adăugare.

După ce am primit cifra. trebuie să o pregătiți pentru muncă. La generarea cheii, am indicat că o vom folosi doar pentru criptare și decriptare. În consecință, Cipher va fi, de asemenea, în aceste scopuri:


unde initDecodeCipher () și initEncodeCiper () sunt:

Nu este greu de observat că cifrul de criptare este oarecum mai dificil de inițializat. Acesta este un escroc al companiei Google, esența căruia cheia publică necesită confirmarea de către utilizator. Noi ocolim această cerință cu ajutorul unei impresii cheie (cârjă, da).

Moment cu KeyPermanentlyInvalidatedException - dacă din anumite motive cheia nu poate fi utilizată, această excepție este declanșată. Motivele posibile includ adăugarea unei imprimări noi la una existentă, schimbarea sau eliminarea completă a blocării. Apoi, cheia nu mai are sens să stocheze și o ștergem.


O metodă care colectează întregul lanț de formare:

Criptare și decriptare


Să descriem o metodă care criptează un argument șir:


Ca rezultat, obținem Base64 - un șir care poate fi stocat în condiții de siguranță în preferințele aplicației.

Pentru a decoda același lucru, folosim următoarea metodă:


Opa, pe intrarea pe care o primește nu numai șirul criptat, ci și obiectul Cipher. De unde a venit, va deveni clar mai târziu.

Degetul greșit


Pentru a utiliza în sfârșit senzorul, trebuie să utilizați metoda FingerprintManagerCompat:


Hendler și steaguri, acum nu avem nevoie, semnalul este utilizat pentru a anula modul cititor de amprente (minimizată cerere, de exemplu), callbacks returnează rezultatul unei anumite lecturi, dar peste kriptoobektom mai multe detalii.

În acest caz, CryptoObject este folosit ca un înveliș pentru Cipher. Pentru ao obține, utilizați metoda:


După cum puteți vedea din cod, cripobiectul este creat de la decryptingCipher. Dacă acest cod este trimis chiar acum la metoda decode (). atunci o excepție va fi aruncată, informându-ne că încercăm să folosim cheia fără confirmare.

Dacă getCryptoObject () revine null. atunci aceasta înseamnă că, atunci când a fost inițializat Chiper, a apărut o excepție KeyPermanentlyInvalidatedException. Nu trebuie făcut nimic decât să lăsați utilizatorul să știe că intrarea pe imprimare nu este disponibilă și va trebui să reintroducă codul PIN.

Așa cum am spus, rezultatele citirii senzorului obținute în metodele de collbare. Iată cum arată:


În cazul recunoașterii reușite, obținem AuthenticationResult. din care putem obține obiectul Cipher cu cheia deja verificată:

Vă mulțumesc pentru atenție.