Para proteger tu sistema de autenticación en Android, considera dejar de usar un modelo basado en contraseñas, en especial para las cuentas sensibles, como las cuentas bancarias y de correo electrónico de tus usuarios. Recuerda que algunas apps que instalan tus usuarios pueden no tener las mejores intenciones y pueden intentar suplantarlos.
Además, no supongas que solo los usuarios autorizados usarán el dispositivo. El robo de teléfonos es un problema común, y los atacantes se enfocan en los dispositivos desbloqueados para obtener ganancias directamente de los datos del usuario o las apps financieras. Sugerimos que todas las apps sensibles implementen un tiempo de espera razonable para la autenticación (¿15 minutos?) con verificación biométrica y que requieran autenticación adicional antes de realizar acciones sensibles, como transferencias de dinero.
Diálogo de autenticación biométrica
La biblioteca de Biometrics ofrece un conjunto de funciones para mostrar un mensaje que solicita autenticación biométrica, como reconocimiento facial o de huellas dactilares. Sin embargo, los mensajes biométricos se pueden configurar para que recurran a LSKF, que tiene riesgos conocidos de visualización no autorizada. En el caso de las apps sensibles, recomendamos no usar el PIN como método alternativo para la autenticación biométrica y, después de agotar los reintentos biométricos, los usuarios pueden esperar, volver a acceder con la contraseña o restablecer las cuentas. El restablecimiento de la cuenta debe requerir factores a los que no se pueda acceder fácilmente en el dispositivo (práctica recomendada a continuación).
Cómo ayuda a mitigar el fraude y el robo de teléfonos
Un caso de uso particular que puede ser útil para evitar fraudes es solicitar la autenticación biométrica dentro de tu app antes de una transacción. Cuando tus usuarios quieran realizar una transacción financiera, se mostrará el diálogo biométrico para verificar que, de hecho, sea el usuario previsto quien realiza la transacción. Esta práctica recomendada protegería contra el robo de un dispositivo por parte de un atacante, independientemente de que este conozca o no la LSKF, ya que deberá demostrar que es el propietario del dispositivo.
Para obtener niveles de seguridad adicionales, recomendamos que los desarrolladores de apps soliciten la autenticación biométrica de clase 3 y utilicen CryptoObject
para las transacciones bancarias y financieras.
Implementación
- Asegúrate de incluir la biblioteca androidx.biometric.
- Incluye el diálogo de acceso biométrico en la actividad o el fragmento que contiene la lógica para la que deseas que se autentique el usuario.
Kotlin
private var executor: Executor? = null private var biometricPrompt: BiometricPrompt? = null private var promptInfo: BiometricPrompt.PromptInfo? = null fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) executor = ContextCompat.getMainExecutor(this) biometricPrompt = BiometricPrompt(this@MainActivity, executor, object : AuthenticationCallback() { fun onAuthenticationError( errorCode: Int, @NonNull errString: CharSequence ) { super.onAuthenticationError(errorCode, errString) Toast.makeText( getApplicationContext(), "Authentication error: $errString", Toast.LENGTH_SHORT ) .show() } fun onAuthenticationSucceeded( @NonNull result: BiometricPrompt.AuthenticationResult? ) { super.onAuthenticationSucceeded(result) Toast.makeText( getApplicationContext(), "Authentication succeeded!", Toast.LENGTH_SHORT ).show() } fun onAuthenticationFailed() { super.onAuthenticationFailed() Toast.makeText( getApplicationContext(), "Authentication failed", Toast.LENGTH_SHORT ) .show() } }) promptInfo = Builder() .setTitle("Biometric login for my app") .setSubtitle("Log in using your biometric credential") .setNegativeButtonText("Use account password") .build() // Prompt appears when user clicks "Log in". // Consider integrating with the keystore to unlock cryptographic operations, // if needed by your app. val biometricLoginButton: Button = findViewById(R.id.biometric_login) biometricLoginButton.setOnClickListener { view -> biometricPrompt.authenticate( promptInfo ) } }
Java
private Executor executor; private BiometricPrompt biometricPrompt; private BiometricPrompt.PromptInfo promptInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); executor = ContextCompat.getMainExecutor(this); biometricPrompt = new BiometricPrompt(MainActivity.this, executor, new BiometricPrompt.AuthenticationCallback() { @Override public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { super.onAuthenticationError(errorCode, errString); Toast.makeText(getApplicationContext(), "Authentication error: " + errString, Toast.LENGTH_SHORT) .show(); } @Override public void onAuthenticationSucceeded( @NonNull BiometricPrompt.AuthenticationResult result) { super.onAuthenticationSucceeded(result); Toast.makeText(getApplicationContext(), "Authentication succeeded!", Toast.LENGTH_SHORT).show(); } @Override public void onAuthenticationFailed() { super.onAuthenticationFailed(); Toast.makeText(getApplicationContext(), "Authentication failed", Toast.LENGTH_SHORT) .show(); } }); promptInfo = new BiometricPrompt.PromptInfo.Builder() .setTitle("Biometric login for my app") .setSubtitle("Log in using your biometric credential") .setNegativeButtonText("Use account password") .build(); // Prompt appears when the user clicks "Log in". // Consider integrating with the keystore to unlock cryptographic operations, // if needed by your app. Button biometricLoginButton = findViewById(R.id.biometric_login); biometricLoginButton.setOnClickListener(view -> { biometricPrompt.authenticate(promptInfo); }); }
Prácticas recomendadas
Te recomendamos que comiences con el codelab para obtener más información sobre la biometría.
Según tus casos de uso, puedes implementar el diálogo con o sin una acción explícita del usuario. Para evitar el fraude, te recomendamos que agregues el diálogo biométrico con una acción explícita del usuario para cada transacción. Entendemos que agregar autenticación puede generar fricción en la UX, pero, debido a la naturaleza de la información que se maneja en una transacción bancaria y a que la autenticación biométrica es más fluida que otros métodos de autenticación, creemos que es necesario agregar este nivel de navegación.
Obtén más información sobre la autenticación biométrica.
Llaves de acceso
Las llaves de acceso son una alternativa más segura y sencilla a las contraseñas. Las llaves de acceso usan criptografía de clave pública para permitir que los usuarios accedan a apps y sitios web con el mecanismo de bloqueo de pantalla de su dispositivo, como la huella dactilar o el reconocimiento facial. Esto libera al usuario de tener que recordar y administrar contraseñas, y proporciona una seguridad significativamente mejorada.
Las llaves de acceso pueden cumplir con los requisitos de autenticación multifactor en un solo paso, ya que reemplazan tanto la contraseña como los códigos OTP para brindar una protección sólida contra los ataques de phishing y evitar la frustración del usuario que genera la experiencia de las contraseñas de un solo uso basadas en SMS o en apps. Dado que las llaves de acceso están estandarizadas, una sola implementación permite una experiencia sin contraseñas en todos los dispositivos, navegadores y sistemas operativos de los usuarios.
En Android, las llaves de acceso se admiten con la biblioteca de Jetpack Credential Manager, que unifica los principales métodos de autenticación, incluidas las llaves de acceso, las contraseñas y el acceso federado (como Acceder con Google).
Cómo ayuda a mitigar el fraude
Las llaves de acceso te protegen de los ataques de phishing porque solo funcionan en tus apps y sitios web registrados.
El componente principal de una llave de acceso es una clave privada criptográfica. Por lo general, esta clave privada reside únicamente en tus dispositivos, como laptops o teléfonos celulares, y los proveedores de credenciales (también conocidos como administradores de contraseñas), como el Administrador de contraseñas de Google, la sincronizan en todos ellos. El servicio en línea solo guarda la clave pública correspondiente cuando se crea una llave de acceso. Durante el acceso, el servicio usa la clave privada para firmar un desafío de la clave pública. Solo puede originarse en uno de tus dispositivos. Además, para que esto ocurra, debes desbloquear tu dispositivo o el almacén de credenciales, lo que evita los accesos no autorizados (por ejemplo, desde un teléfono robado).
Para evitar el acceso no autorizado en caso de robo de un dispositivo desbloqueado, las llaves de acceso deben combinarse con un período de espera de autenticación razonable. Un atacante que roba un dispositivo no debería poder usar una aplicación solo porque el usuario anterior había accedido. En cambio, las credenciales deben vencer a intervalos regulares (por ejemplo, cada 15 minutos), y se debe solicitar a los usuarios que verifiquen su identidad a través de la reautenticación del bloqueo de pantalla.
Si te roban el teléfono, las llaves de acceso te protegen porque los ladrones no pueden robar tus contraseñas para usarlas en otros dispositivos, ya que las llaves de acceso son específicas para cada dispositivo. Si usas el Administrador de contraseñas de Google y te roban el teléfono, puedes acceder a tu Cuenta de Google desde otro dispositivo (como una computadora) y salir de ella de forma remota en el teléfono robado. Esto hace que el Administrador de contraseñas de Google en el teléfono robado sea inutilizable, incluidas las llaves de acceso guardadas.
En el peor de los casos, si no se recupera el dispositivo robado, el proveedor de credenciales que creó y sincronizó la llave de acceso la volverá a sincronizar con el dispositivo nuevo. Por ejemplo, es posible que el usuario haya elegido el Administrador de contraseñas de Google para crear la llave de acceso y pueda acceder a ella en un dispositivo nuevo volviendo a acceder a su Cuenta de Google y proporcionando el bloqueo de pantalla del dispositivo anterior.
Obtén más información en el artículo Seguridad de las llaves de acceso en el Administrador de contraseñas de Google.
Implementación
Las llaves de acceso son compatibles con dispositivos que ejecutan Android 9 (nivel de API 28) o versiones posteriores. Las contraseñas y Acceder con Google son compatibles a partir de Android 4.4. Para comenzar a usar llaves de acceso, sigue estos pasos:
- Sigue el codelab de Credential Manager para comprender cómo implementar llaves de acceso.
- Revisa los lineamientos de diseño de la experiencia del usuario con llaves de acceso. En este documento, se muestran los flujos recomendados para tu caso de uso.
- Estudia el Administrador de credenciales siguiendo la guía.
- Planifica la implementación del Administrador de credenciales y las llaves de acceso para tu app. Planifica la incorporación de compatibilidad con Vínculos de recursos digitales.
Consulta nuestra documentación para desarrolladores para obtener más detalles sobre cómo crear, registrar y autenticar con llaves de acceso.
Restablecimiento seguro de la cuenta
Un atacante no autorizado con acceso a un dispositivo desbloqueado (por ejemplo, cuando se roba un teléfono) intentará acceder a apps sensibles, en especial, apps bancarias o de efectivo. Si la app implementa la verificación biométrica, el atacante intentará restablecer la cuenta para ingresar. Es fundamental que el flujo de restablecimiento de la cuenta no se base únicamente en información a la que se pueda acceder fácilmente en el dispositivo, como los vínculos de restablecimiento de OTP por correo electrónico o SMS.
A continuación, se incluyen algunas prácticas recomendadas comunes que puedes incorporar en el flujo de restablecimiento de tu app:
- Reconocimiento facial, además de la OTP
- Preguntas de seguridad
- Factor de conocimiento (como el apellido de soltera de la madre, la ciudad de nacimiento o la canción favorita)
- Verificación por documento de identidad
API de SMS Retriever
La API de SMS Retriever te permite realizar automáticamente la verificación del usuario basada en SMS en tu app para Android. De esa manera, no se le pedirá al usuario que escriba los códigos de verificación de forma manual. Además, esta API no le solicita al usuario permisos adicionales y potencialmente peligrosos de la app, como RECEIVE_SMS
o READ_SMS
. Sin embargo, no se debe usar el SMS como la única verificación del usuario para protegerse contra el acceso local no autorizado al dispositivo.
Cómo ayuda a mitigar el fraude
Algunos usuarios usan códigos por SMS como su único factor de autenticación, lo que proporciona un punto de entrada fácil para el fraude.
La API de SMS Retriever permite que la app recupere directamente el código SMS sin interacción del usuario y puede proporcionar un nivel de protección contra el fraude.
Implementación
La implementación de la API de SMS Retriever consta de dos partes: Android y servidor.
Android: (guía)
- Obtén el número de teléfono del usuario.
- Inicia el cliente de SMS Retriever.
- Envía el número de teléfono a tu servidor.
- Recibir mensajes de verificación
- Envía la OTP a tu servidor.
Servidor: (guía)
- Construye un mensaje de verificación.
- Enviar el mensaje de verificación por SMS
- Verifica la OTP cuando se devuelva.
Prácticas recomendadas
Una vez que se integra la app y se verifica el número de teléfono del usuario con la API de SMS Retriever, se intenta obtener la OTP. Si se realiza correctamente, es una señal sólida de que el SMS se recibió automáticamente en el dispositivo. Si no se realiza correctamente y el usuario debe escribir el OTP de forma manual, puede ser una señal de advertencia de que el usuario puede estar sufriendo un fraude.
No se debe usar el SMS como el único mecanismo de verificación del usuario, ya que deja lugar a ataques locales, como un atacante que roba un dispositivo desbloqueado, o ataques de clonación de SIM. Se recomienda usar la biometría siempre que sea posible. En los dispositivos en los que no hay sensores biométricos disponibles, la autenticación del usuario debe basarse en al menos un factor que no se pueda obtener fácilmente del dispositivo actual.
Más información
Para obtener más información sobre las prácticas recomendadas, consulta los siguientes recursos:
- Nuestra documentación de Android sobre seguridad
- Documentación de la API de Play Integrity
- Cambios en Android 15
- Prácticas recomendadas para evitar llamadas fraudulentas de Monzo Bank