A autenticação de impressão digital utiliza o sensor de toque incorporado em muitos dispositivos Android para identificar o usuário e fornecer acesso tanto ao dispositivo como à funcionalidade do aplicativo, tais como opções de pagamento emapp. A implementação da autenticação por impressão digital é um processo em várias etapas que pode, a princípio, parecer avassalador. Quando decomposto em etapas individuais, no entanto, o processo torna-se muito menos complexo. Em termos básicos, a autenticação de impressões digitais é principalmente uma questão de encriptação envolvendo uma chave, uma cifra para executar a encriptação e um gestor de impressões digitais para lidar com o processo de autenticação.
Este capítulo fornece tanto uma visão geral da autenticação de impressões digitais como um tutorial detalhado, passo a passo, que demonstra uma abordagem prática à implementação.
>
Um resumo da autenticação de impressões digitais
Existem essencialmente 10 passos para implementar a autenticação de impressões digitais dentro de uma aplicação Android. Estes passos podem ser resumidos da seguinte forma:
1. Peça permissão de autenticação de impressão digital dentro do ficheiro Manifesto do projecto.
2. Verifique se a tela de bloqueio do dispositivo no qual a aplicação está a ser executada está protegida por um PIN, padrão ou palavra-passe (as impressões digitais só podem ser registadas em dispositivos nos quais a tela de bloqueio tenha sido protegida).
3. Verifique se pelo menos uma impressão digital foi registada no dispositivo.
4. Crie uma instância da classe FingerprintManager.
5. Utilize uma instância do Keystore para obter acesso ao contentor do Android Keystore. Esta é uma área de armazenamento utilizada para o armazenamento seguro de chaves criptográficas em dispositivos Android.
6. Gere uma chave de encriptação utilizando a classe KeyGenerator e armazene-a no contentor Keystore.
7. Inicialize uma instância da classe Cipher usando a chave gerada no passo 5.
8. Use a instância Cipher para criar um CryptoObject e atribua-o à instância FingerprintManager criada no passo 4.
9. Chame o método de autenticação da instância do FingerprintManager.
10. Implementar métodos para lidar com os callbacks acionados pelo processo de autenticação. Fornecer acesso ao conteúdo ou funcionalidade protegida na conclusão de uma autenticação bem sucedida.
Cada um dos passos acima será coberto com mais detalhes ao longo do tutorial delineado no resto deste capítulo.
Criar o Projeto de Autenticação de Impressões Digitais
Inicie este exemplo lançando o ambiente Android Studio e criando um novo projeto, inserindo FingerprintDemo no campo Application name e ebookfrenzy.com como a configuração do Domínio da Empresa antes de clicar no botão Next.
Na tela de fatores do formulário, ative a opção Phone and Tablet e defina a configuração mínima do SDK para API 23: Android 6.0 (Marshmallow). Continue através das telas de configuração, solicitando a criação de uma atividade vazia chamada FingerprintDemoActivity com um layout correspondente chamado activity_fingerprint_demo.
Configuring Device Fingerprint Authentication
A autenticação de impressão digital só está disponível em dispositivos que contenham um sensor de toque e nos quais os passos de configuração apropriados foram tomados para proteger o dispositivo e registrar pelo menos uma impressão digital. Para obter as etapas de configuração de uma sessão de emulador para testar a autenticação de impressões digitais, consulte o capítulo intitulado Utilizando e Configurando o Emulador AVD do Android Studio 2.
>
Para configurar a autenticação de impressões digitais em um dispositivo físico, comece abrindo o aplicativo Configurações e selecionando a opção Segurança. Dentro da tela Configurações de segurança, selecione a opção Impressão digital. Na tela de informações resultantes, clique no botão Continuar para ir para a tela de configuração de Impressões Digitais. Antes que a segurança das impressões digitais possa ser ativada, é necessário configurar um método de desbloqueio da tela de backup (como um número PIN). Clique no botão Configurar Bloqueio da Tela se a tela de bloqueio ainda não estiver protegida e siga as etapas para configurar o PIN, padrão ou senha de segurança.
Com a tela de bloqueio protegida, vá para a tela de detecção de impressões digitais e toque no sensor quando solicitado (Figura 62-1), repetindo o processo para adicionar impressões digitais adicionais, se necessário.
Figure 62-1
Adicionar a permissão de impressão digital ao ficheiro de manifesto
A autenticação de impressão digital requer que o aplicativo solicite a permissão USE_FINGERPRINT dentro do ficheiro de manifesto do projecto. Dentro da janela de ferramentas do projeto Android Studio Localize e edite o aplicativo -> Manifests ->Arquivo AndroidManifest.xml para adicionar a solicitação de permissão como segue:
Downloading the Fingerprint Icon
Google fornece um ícone padrão (Figura 62-2) que deve ser exibido sempre que um aplicativo solicitar a autenticação de um usuário.
Figure 62-2
Pode ser baixada uma cópia deste ícone da seguinte URL:
Abra o navegador do sistema de arquivos para o seu sistema operacional, selecione a imagem recém baixada e pressione Ctrl-C (Cmd-C no Mac OS X) para copiar o arquivo. Volte ao Android Studio, clique com o botão direito do mouse no aplicativo -> res -> pasta extraível e selecione a opção do menu Colar para adicionar uma cópia do arquivo de imagem ao projeto. Quando a caixa de diálogo Copiar aparecer, clique no botão OK para usar as configurações padrão.
Designing the User Interface
No interesse de manter o exemplo o mais simples possível, os únicos elementos dentro da interface do usuário serão um TextView e um ImageView. Localize e selecione o arquivo de recurso activity_fingerprint_demo.xml para carregá-lo na ferramenta Designer. Uma vez carregado, exclua a amostra do objeto TextView, arraste e solte um objeto ImageView do painel e posicione-o no centro da tela de layout.
No painel Properties, localize o atributo src, clique no campo de texto correspondente seguido do botão destacado na Figura 62-3 para exibir o diálogo Resources:
Figure 62-3
No painel esquerdo do diálogo selecione a opção Drawable. Dentro do painel principal, digite ic_fp na caixa de busca como ilustrado na Figura 62 4 para localizar o ícone da impressão digital. Selecione o ícone da caixa de diálogo e clique em OK para atribuí-lo ao objeto ImageView.
Figure 62-4
Localize o objeto Texto Grande da paleta e arraste-o e solte-o para que fique posicionado abaixo do objeto ImageView. Clique duas vezes sobre o objeto e altere o texto para que ele leia “Touch Sensor”. Use o ícone da lâmpada para extrair a string para um recurso chamado touch_sensor.
>
Ao completar os passos acima, o layout deve corresponder ao mostrado na Figura 62-5:
Figure 62-5
Acesso ao Keyguard and Fingerprint Manager Services
A autenticação de impressão digital faz uso de dois serviços do sistema na forma do KeyguardManager e do FingerprintManager. Edite o método onCreate localizado no ficheiro FingerprintDemoActivity.java para obter referências a estes dois serviços da seguinte forma:
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); }}
Verificando as Configurações de Segurança
Anteriormente neste capítulo foram dados passos para configurar a tela de bloqueio e registar as impressões digitais no dispositivo ou emulador no qual o aplicativo vai ser testado. É importante, no entanto, incluir código defensivo no aplicativo para garantir que esses requisitos tenham sido atendidos antes de tentar obter a autenticação da impressão digital. Estes passos serão realizados dentro do método onCreate residente no arquivo FingerprintDemoActivity.java, fazendo uso dos serviços de Keyguard e Fingerprint Manager. Note que o código também foi adicionado para verificar se a permissão USE_FINGERPRINT foi configurada para o app:
As alterações de código acima começam por utilizar o Keyguard manager para verificar se foi configurado um método de desbloqueio do ecrã de backup (por outras palavras, pode ser utilizado um PIN ou outro método de autenticação como alternativa à autenticação por impressão digital para desbloquear o ecrã). Caso o ecrã de bloqueio não esteja protegido, o código reporta o problema ao utilizador e retorna a partir do método.
O gestor de impressões digitais é então utilizado para verificar se pelo menos uma impressão digital foi registada no dispositivo, mais uma vez reporta o problema e retorna a partir do método, se necessário.
Acesso à Keystore Android e KeyGenerator
Parte do processo de autenticação da impressão digital envolve a geração de uma chave de encriptação que é depois armazenada de forma segura no dispositivo utilizando o sistema Android Keystore. Antes que a chave possa ser gerada e armazenada, o aplicativo deve primeiro obter acesso ao Keystore. Um novo método chamado generateKey será agora implementado dentro do arquivo FingerprintDemoActivity.java para realizar a geração da chave e tarefas de armazenamento. Inicialmente, apenas o código de acesso ao Keystore será adicionado da seguinte forma:
Uma referência ao Keystore é obtida chamando o método getInstance da classe Keystore e passando pelo identificador do contentor standard do Android keystore (“AndroidKeyStore”). O próximo passo no tutorial será gerar uma chave utilizando o serviço KeyGenerator. Antes de gerar esta chave, é necessário adicionar código para obter uma referência a uma instância do KeyGenerator, passando como argumentos o tipo de chave a ser gerada e o nome do contentor Keystore no qual a chave será guardada:
Gerar a chave
Agora temos uma referência ao contentor Android Keystore e a uma instância KeyGenerator, o passo seguinte é gerar a chave que será utilizada para criar uma cifra para o processo de encriptação. Permanecendo dentro do arquivo FingerprintDemoActivity.java, adicione este novo código como segue:
As alterações acima requerem alguma explicação. Após importar um número de módulos adicionais o código declara uma variável string representando o nome (neste caso “example_key”) que será usada quando armazenar a chave no contentor Keystore.
Next, o contentor Keystore é carregado e o KeyGenerator é inicializado. Este processo de inicialização faz uso da classe KeyGenParameterSpec.Builder para especificar o tipo de chave a ser gerada. Isto inclui referenciar o nome da chave, configurar a chave de forma a que possa ser utilizada tanto para encriptação como para desencriptação, e definir vários parâmetros de encriptação. O setUserAuthenticationRequired method call configura a chave de forma a que o utilizador seja obrigado a autorizar cada utilização da chave com uma autenticação de impressão digital. Uma vez configurado o KeyGenerator, ele é então utilizado para gerar a chave através de uma chamada ao método generateKey da instância.
Initializing the Cipher
Agora a chave tenha sido gerada o próximo passo é inicializar a cifra que será utilizada para criar a instância criptografada FingerprintManager.CryptoObject. Este CryptoObject, por sua vez, será utilizado durante o processo de autenticação da impressão digital. A configuração da cifra envolve a obtenção de uma instância cifrada e sua inicialização com a chave armazenada no container do Keystore. Adicione um novo método chamado cipherInit ao arquivo FingerprintDemoActivity.java para realizar estas tarefas:
O método getInstance da classe Cipher é chamado para obter uma instância Cipher que é posteriormente configurada com as propriedades necessárias para a autenticação da impressão digital. A chave gerada anteriormente é então extraída do contentor Keystore e utilizada para inicializar a instância Cipher. Os erros são tratados de acordo e um resultado verdadeiro ou falso é retornado com base no sucesso ou não do processo de inicialização da cifra.
O trabalho está agora completo nos métodos generateKey e cipherInit. O próximo passo é modificar o método onCreate para chamar esses métodos e, no caso de uma inicialização com sucesso da cifra, criar uma instância CryptoObject.
Criando a Instância CryptoObject
Remaining within the FingerprintDemoActivity.java, modifique o método onCreate para chamar os dois métodos recentemente criados e gerar o CryptoObject da seguinte forma:
A tarefa final no projecto é implementar uma nova classe para lidar com a autenticação da impressão digital real.
Implementing the Fingerprint Authentication Handler Class
Até agora, neste capítulo, a maior parte do trabalho tem envolvido a preparação para a autenticação da impressão digital em termos da chave, cifra e objecto criptográfico. A autenticação real é acionada através de uma chamada para o método de autenticação da instância FingerprintManager. Esta chamada de método, no entanto, irá disparar um dos vários eventos de retorno de chamada, dependendo do sucesso ou fracasso da autenticação. Tanto a chamada do método de autenticação quanto o método de retorno de chamada precisam ser implementados em uma classe que estenda a classe FingerprintManager.AuthenticationCallback. Tal classe agora precisa ser adicionada ao project.
Navigate ao app -> java -> com.ebookfrenzy.fingerprintdemo entry dentro da janela da ferramenta Project do Android Studio e clique com o botão direito do mouse sobre ela. No menu resultante, selecione a opção New -> Java Class para exibir o diálogo Create New Class (Criar Nova Classe). Nomeie a classe FingerprintHandler e clique no botão OK para criar a classe.
Editar o novo arquivo de classe para que ele estenda o FingerprintManager.AuthenticationCallback, importa alguns módulos adicionais e implementa um método construtor que permitirá que o contexto do aplicativo seja passado quando uma instância da classe for criada (o contexto será usado nos métodos de callback para notificar o usuário sobre o status de autenticação):
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; }}
Próximo um método precisa ser adicionado que pode ser chamado para iniciar a autenticação da impressão digital. Quando chamado, este método terá de passar pelas instâncias FingerprintManager e CryptoObject. Nomeie este método startAuth e implemente-o no FingerprintHandler.java da seguinte forma (note que também foi adicionado código para verificar novamente se a permissão de impressão digital foi concedida):
Next, adicione os métodos callback handler, cada um dos quais implementado para exibir uma mensagem de brinde indicando o resultado da autenticação da impressão digital:
A tarefa final antes de testar o projecto é modificar o método onCreate para que ele crie uma nova instância da classe FingerprintHandler e chame o método startAuth. Edite o arquivo FingerprintDemoActivity.java e modifique o final do método onCreate para que ele leia como a seguir:
Testar o Projeto
Com o projeto agora completo execute o aplicativo em um dispositivo físico Android ou sessão de emulador. Uma vez executado, toque no sensor de impressão digital ou use o painel de controles estendido dentro do emulador para simular um toque de impressão digital como descrito no capítulo intitulado Usando e Configurando o Emulador de AVD do Android Studio 2. Assumindo que uma impressão digital registada é detectada, aparecerá uma mensagem de brinde indicando uma autenticação bem sucedida, conforme mostrado na Figura 62-6:
>
>
Figure 62-6
Para a aplicação em execução e relança-a, desta vez utilizando uma impressão digital não registada para tentar a autenticação. Desta vez deve aparecer uma mensagem de brinde indicando que a autenticação falhou.
Sumário
A autenticação da impressão digital no Android é um processo em várias etapas que inicialmente pode parecer complexo. Quando decomposto em etapas individuais, no entanto, o processo torna-se mais claro. A autenticação de impressão digital envolve o uso de chaves, cifras e armazenamento de chaves combinado com as características da classe FingerprintManager. Este capítulo forneceu uma introdução a estas etapas e trabalhou através da criação de um projecto de aplicação de exemplo destinado a mostrar a implementação prática da autenticação de impressões digitais no Android.