La autenticación de huellas dactilares utiliza el sensor táctil incorporado en muchos dispositivos Android para identificar al usuario y proporcionarle acceso tanto al dispositivo como a la funcionalidad de la aplicación, como las opciones de pago dentro de la aplicación. La implementación de la autenticación por huella dactilar es un proceso de varios pasos que, al principio, puede parecer abrumador. Sin embargo, cuando se desglosa en pasos individuales, el proceso se vuelve mucho menos complejo. En términos básicos, la autenticación de huellas dactilares es principalmente una cuestión de encriptación que implica una clave, un cifrado para realizar la encriptación y un gestor de huellas dactilares para manejar el proceso de autenticación.
Este capítulo proporciona tanto una visión general de la autenticación de huellas dactilares como un tutorial detallado, paso a paso, que demuestra un enfoque práctico para la implementación.
Una visión general de la autenticación de huellas dactilares
Esencialmente hay 10 pasos para implementar la autenticación de huellas dactilares dentro de una aplicación Android. Estos pasos se pueden resumir como sigue:
1. Solicitar el permiso de autenticación por huella dactilar dentro del archivo Manifest del proyecto.
2. Verificar que la pantalla de bloqueo del dispositivo en el que se ejecuta la app está protegida por un PIN, un patrón o una contraseña (las huellas dactilares sólo pueden registrarse en dispositivos en los que la pantalla de bloqueo ha sido protegida).
3. Verificar que se ha registrado al menos una huella dactilar en el dispositivo.
4. Crear una instancia de la clase FingerprintManager.
5. Utilizar una instancia de Keystore para acceder al contenedor de Android Keystore. Este es un área de almacenamiento utilizada para el almacenamiento seguro de claves criptográficas en los dispositivos Android.
6. Generar una clave de cifrado utilizando la clase KeyGenerator y almacenarla en el contenedor Keystore.
7. Inicializar una instancia de la clase Cipher utilizando la clave generada en el paso 5.
8. Utilizar la instancia Cipher para crear un CryptoObject y asignarlo a la instancia FingerprintManager creada en el paso 4.
9. Llame al método authenticate de la instancia FingerprintManager.
10. Implementar métodos para manejar las devoluciones de llamada desencadenadas por el proceso de autenticación. Proporcionar acceso al contenido o funcionalidad protegida al completar una autenticación exitosa.
Cada uno de los pasos anteriores se cubrirá con mayor detalle a lo largo del tutorial que se describe en el resto de este capítulo.
Crear el proyecto de autenticación de huellas dactilares
Comienza este ejemplo iniciando el entorno de Android Studio y creando un nuevo proyecto, introduciendo FingerprintDemo en el campo Application name y ebookfrenzy.com como la configuración de Dominio de la empresa antes de hacer clic en el botón Siguiente.
En la pantalla de factores de forma, active la opción de Teléfono y Tableta y establezca la configuración mínima de SDK en API 23: Android 6.0 (Marshmallow). Continúe a través de las pantallas de configuración, solicitando la creación de una actividad vacía denominada FingerprintDemoActivity con un diseño correspondiente denominado activity_fingerprint_demo.
Configuración de la autenticación de huellas dactilares del dispositivo
La autenticación de huellas dactilares solo está disponible en dispositivos que contengan un sensor táctil y en los que se hayan realizado los pasos de configuración adecuados para asegurar el dispositivo e inscribir al menos una huella dactilar. Para conocer los pasos de configuración de una sesión de emulador para probar la autenticación por huella dactilar, consulte el capítulo titulado Uso y configuración del emulador AVD de Android Studio 2.
Para configurar la autenticación por huella dactilar en un dispositivo físico, comience abriendo la aplicación Ajustes y seleccionando la opción Seguridad. Dentro de la pantalla de configuración de seguridad, selecciona la opción de huella dactilar. En la pantalla de información resultante pulse el botón Continuar para pasar a la pantalla de configuración de la huella dactilar. Antes de habilitar la seguridad por huella dactilar se debe configurar un método de desbloqueo de pantalla de respaldo (como un número PIN). Haga clic en el botón Configurar bloqueo de pantalla si la pantalla de bloqueo no está ya asegurada y siga los pasos para configurar la seguridad mediante PIN, patrón o contraseña.
Con la pantalla de bloqueo asegurada, proceda a la pantalla de detección de huellas dactilares y toque el sensor cuando se le indique (Figura 62-1), repitiendo el proceso para añadir huellas dactilares adicionales si es necesario.
Figura 62-1
Añadir el permiso de huella dactilar al archivo de manifiesto
La autenticación por huella dactilar requiere que la app solicite el permiso USE_FINGERPRINT dentro del archivo de manifiesto del proyecto. Dentro de la ventana de la herramienta Android Studio Project localice y edite el archivo app -> manifests -> AndroidManifest.xml para añadir la solicitud de permiso de la siguiente manera:
Descargando el icono de la huella dactilar
Google proporciona un icono estándar (Figura 62-2) que debe mostrarse siempre que una app solicite la autenticación de un usuario.
Figura 62-2
Una copia de este icono puede descargarse desde la siguiente URL:
Abra el navegador del sistema de archivos de su sistema operativo, seleccione la imagen recién descargada y pulse Ctrl-C (Cmd-C en Mac OS X) para copiar el archivo. Vuelve a Android Studio, haz clic con el botón derecho del ratón en la carpeta de la aplicación -> res -> dibujable y selecciona la opción de menú Pegar para añadir una copia del archivo de imagen al proyecto. Cuando aparezca el cuadro de diálogo Copiar, haga clic en el botón Aceptar para utilizar la configuración predeterminada.
Diseño de la interfaz de usuario
En aras de mantener el ejemplo lo más simple posible, los únicos elementos dentro de la interfaz de usuario serán un TextView y un ImageView. Localice y seleccione el archivo activity_fingerprint_demo.xml layout resource para cargarlo en la herramienta Designer. Una vez cargado, elimine el objeto TextView de muestra, arrastre y suelte un objeto ImageView del panel y colóquelo en el centro del lienzo de diseño.
Dentro del panel de Propiedades, localice el atributo src, haga clic en el campo de texto correspondiente seguido del botón resaltado en la Figura 62-3 para mostrar el diálogo de Recursos:
Figura 62-3
Desde el panel izquierdo del diálogo seleccione la opción Dibujable. Dentro del panel principal, introduzca ic_fp en el cuadro de búsqueda como se ilustra en la Figura 62 4 para localizar el icono de la huella digital. Seleccione el icono en el cuadro de diálogo y haga clic en Aceptar para asignarlo al objeto ImageView.
Figura 62-4
Localice el objeto Large Text de la paleta y arrástrelo y suéltelo para que se sitúe debajo del objeto ImageView. Haga doble clic en el objeto y cambie el texto para que diga «Sensor táctil». Utilice el icono de la bombilla para extraer la cadena a un recurso llamado touch_sensor.
Una vez completados los pasos anteriores, el diseño debería coincidir con el mostrado en la Figura 62-5:
Figura 62-5
Acceso a los servicios Keyguard y Fingerprint Manager
La autenticación de huellas dactilares hace uso de dos servicios del sistema en forma de KeyguardManager y FingerprintManager. Edita el método onCreate ubicado en el archivo FingerprintDemoActivity.java para obtener las referencias a estos dos servicios de la siguiente manera:
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); }}
Comprobando la configuración de seguridad
Al principio de este capítulo se dieron los pasos para configurar la pantalla de bloqueo y registrar las huellas digitales en el dispositivo o emulador en el que se va a probar la app. Sin embargo, es importante incluir código defensivo en la app para asegurarse de que estos requisitos se han cumplido antes de intentar buscar la autenticación de huellas dactilares. Estos pasos se realizarán dentro del método onCreate que reside en el archivo FingerprintDemoActivity.java, haciendo uso de los servicios Keyguard y Fingerprint manager. Obsérvese que también se ha añadido código para verificar que se ha configurado el permiso USE_FINGERPRINT para la app:
Los cambios de código anteriores comienzan utilizando el gestor Keyguard para verificar que se ha configurado un método de desbloqueo de pantalla de respaldo (en otras palabras, se puede utilizar un PIN u otro método de autenticación como alternativa a la autenticación por huella dactilar para desbloquear la pantalla). En el caso de que la pantalla de bloqueo no esté asegurada, el código informa del problema al usuario y vuelve del método.
El gestor de huellas dactilares se utiliza entonces para verificar que se ha registrado al menos una huella dactilar en el dispositivo, informando de nuevo del problema y volviendo del método si es necesario.
Acceso al almacén de claves de Android y al generador de claves
Parte del proceso de autenticación de huellas dactilares implica la generación de una clave de cifrado que luego se almacena de forma segura en el dispositivo utilizando el sistema de almacén de claves de Android. Antes de que la clave pueda ser generada y almacenada, la aplicación debe primero obtener acceso al Keystore. Ahora se implementará un nuevo método llamado generateKey dentro del archivo FingerprintDemoActivity.java para realizar las tareas de generación y almacenamiento de la clave. Inicialmente, sólo se añadirá el código para acceder al Keystore de la siguiente manera:
Una referencia al Keystore se obtiene llamando al método getInstance de la clase Keystore y pasando el identificador del contenedor estándar de Android keystore («AndroidKeyStore»). El siguiente paso en el tutorial será generar una clave utilizando el servicio KeyGenerator. Antes de generar esta clave, es necesario añadir código para obtener una referencia a una instancia del KeyGenerator, pasando como argumentos el tipo de clave a generar y el nombre del contenedor Keystore en el que se va a guardar la clave:
Generando la clave
Ahora que tenemos una referencia al contenedor Android Keystore y una instancia KeyGenerator, el siguiente paso es generar la clave que se utilizará para crear un cifrado para el proceso de cifrado. Siguiendo dentro del archivo FingerprintDemoActivity.java, añade este nuevo código de la siguiente manera:
Los cambios anteriores requieren alguna explicación. Después de importar una serie de módulos adicionales, el código declara una variable de cadena que representa el nombre (en este caso «example_key») que se utilizará al almacenar la clave en el contenedor Keystore.
A continuación, se carga el contenedor Keystore y se inicializa el KeyGenerator. Este proceso de inicialización hace uso de la clase KeyGenParameterSpec.Builder para especificar el tipo de clave que se está generando. Esto incluye la referencia al nombre de la clave, la configuración de la clave para que pueda ser utilizada tanto para el cifrado como para el descifrado, y la configuración de varios parámetros de cifrado. La llamada al método setUserAuthenticationRequired configura la clave de manera que el usuario deba autorizar cada uso de la clave con una autenticación de huella digital. Una vez configurado el KeyGenerator, se utiliza para generar la clave a través de una llamada al método generateKey de la instancia.
Inicialización del cifrado
Ahora que se ha generado la clave, el siguiente paso es inicializar el cifrado que se utilizará para crear la instancia FingerprintManager.CryptoObject cifrada. Este CryptoObject se utilizará, a su vez, durante el proceso de autenticación de huellas dactilares. La configuración del cifrado implica obtener una instancia de Cipher e inicializarla con la clave almacenada en el contenedor Keystore. Añade un nuevo método llamado cipherInit al archivo FingerprintDemoActivity.java para realizar estas tareas:
Se llama al método getInstance de la clase Cipher para obtener una instancia de Cipher que posteriormente se configura con las propiedades necesarias para la autenticación de la huella. La clave generada previamente se extrae del contenedor Keystore y se utiliza para inicializar la instancia Cipher. Los errores se manejan como corresponde y se devuelve un resultado verdadero o falso basado en el éxito o no del proceso de inicialización del cifrado.
Ahora se ha completado el trabajo en los métodos generateKey y cipherInit. El siguiente paso es modificar el método onCreate para llamar a estos métodos y, en caso de que la inicialización del cifrado sea exitosa, crear una instancia de CryptoObject.
Creación de la instancia de CryptoObject
Dentro del archivo FingerprintDemoActivity.java, modifique el método onCreate para llamar a los dos métodos recién creados y genere el CryptoObject de la siguiente manera:
La tarea final en el proyecto es implementar una nueva clase para manejar la autenticación real de la huella digital.
Implementación de la clase manejadora de la autenticación de la huella digital
Hasta ahora en este capítulo la mayor parte del trabajo ha implicado la preparación de la autenticación de la huella digital en términos de la clave, el cifrado y el objeto crypto. La autenticación real se desencadena a través de una llamada al método authenticate de la instancia FingerprintManager. Esta llamada al método, sin embargo, desencadenará uno de varios eventos de devolución de llamada dependiendo del éxito o el fracaso de la autenticación. Tanto la llamada al método authenticate como los métodos callback handler deben implementarse en una clase que extienda la clase FingerprintManager.AuthenticationCallback. Dicha clase debe ser añadida al proyecto.
Navega hasta la aplicación -> java -> com.ebookfrenzy.fingerprintdemo dentro de la ventana de la herramienta Android Studio Project y haz clic con el botón derecho del ratón sobre ella. En el menú resultante, seleccione la opción Nueva -> Clase Java para mostrar el cuadro de diálogo Crear Nueva Clase. Nombra la clase FingerprintHandler y haz clic en el botón OK para crear la clase.
Edita el nuevo archivo de clase para que extienda FingerprintManager.AuthenticationCallback, importe algunos módulos adicionales e implemente un método constructor que permita pasar el contexto de la aplicación cuando se cree una instancia de la clase (el contexto se utilizará en los métodos de callback para notificar al usuario el estado de la autenticación):
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; }}
A continuación hay que añadir un método que pueda ser llamado para iniciar la autenticación de la huella digital. Cuando se llame a este método habrá que pasarle las instancias FingerprintManager y CryptoObject. Nombre este método startAuth e impleméntelo en el archivo de clase FingerprintHandler.java de la siguiente manera (tenga en cuenta que también se ha añadido código para comprobar una vez más que se ha concedido el permiso de huellas dactilares):
A continuación, añada los métodos de control de devolución de llamada, cada uno de los cuales se implementa para mostrar un mensaje de brindis que indica el resultado de la autenticación de huellas dactilares:
La tarea final antes de probar el proyecto es modificar el método onCreate para que cree una nueva instancia de la clase FingerprintHandler y llame al método startAuth. Edita el archivo FingerprintDemoActivity.java y modifica el final del método onCreate para que diga lo siguiente:
Probando el proyecto
Con el proyecto ahora completo ejecute la aplicación en un dispositivo Android físico o en una sesión del emulador. Una vez que se ejecute, toque el sensor de huellas dactilares o utilice el panel de controles extendidos dentro del emulador para simular un toque de huellas dactilares como se indica en el capítulo titulado Uso y configuración del emulador AVD de Android Studio 2. Suponiendo que se detecte una huella digital registrada, aparecerá un mensaje de tostado indicando una autenticación exitosa como se muestra en la Figura 62-6:
Figura 62-6
Detenga la aplicación que se está ejecutando y vuelva a iniciarla, esta vez utilizando una huella digital no registrada para intentar la autenticación. Esta vez debería aparecer un mensaje de tostado indicando que la autenticación ha fallado.
Resumen
La autenticación por huella dactilar en Android es un proceso de varios pasos que puede parecer inicialmente complejo. Sin embargo, cuando se desglosa en pasos individuales, el proceso se vuelve más claro. La autenticación de huellas dactilares implica el uso de claves, cifrados y almacenamiento de claves combinados con las características de la clase FingerprintManager. Este capítulo ha proporcionado una introducción a estos pasos y ha trabajado en la creación de un proyecto de aplicación de ejemplo destinado a mostrar la implementación práctica de la autenticación de huellas dactilares dentro de Android.