La respuesta corta

La autenticación reforzada de cliente exige dos elementos de categorías distintas —algo que sabes, algo que tienes, algo que eres— y que sean independientes entre sí: comprometer uno no puede comprometer al otro.

De ahí sale el error más común en apps bancarias: creer que poner una huella ya cumple. Una huella sola no son dos factores. Lo que sí cumple es el patrón correcto: la biometría —inherencia— desbloquea una clave criptográfica ligada al dispositivo —posesión—, y es esa clave la que firma la operación. Dos elementos, dos categorías, e independencia real, porque la clave vive en hardware y no sale de ahí.

Y hay un requisito que se olvida más que ninguno: el código de autenticación tiene que estar vinculado dinámicamente al importe y al beneficiario concretos de esa operación. Si tu pantalla de confirmación no enseña esos dos datos, no cumples aunque la criptografía sea impecable.

Lo que dice la norma

El marco es el Reglamento Delegado (UE) 2018/389, que desarrolla PSD2 en materia de autenticación reforzada y comunicación segura. Entró en vigor el 14 de marzo de 2018 y sus obligaciones se aplican desde el 14 de septiembre de 2019, tras el periodo transitorio de 18 meses.

Dos piezas que condicionan directamente el diseño de la app:

Vinculación dinámica. Para pagos electrónicos remotos, la autenticación reforzada debe incluir elementos que vinculen dinámicamente la operación con un importe y un beneficiario concretos. En la práctica: el usuario ve en la pantalla de aprobación cuánto y a quién, y el código que se genera solo vale para esa combinación. Cambiar el importe después invalida la autorización.

Exenciones. Existen varias, y la de pago contactless en punto de venta tiene umbrales concretos: el proveedor puede no aplicar autenticación reforzada si el importe individual no supera los 50 EUR y, además, el valor acumulado de las operaciones contactless previas no supera los 150 EUR o el número de operaciones contactless consecutivas desde la última autenticación es menor de cinco.

Las demás exenciones —beneficiarios de confianza, operaciones recurrentes, bajo importe en remoto, análisis de riesgo de la operación— tienen sus propios umbrales y condiciones, y conviene contrastarlas contra el texto consolidado antes de fijar una regla de negocio: no es un sitio donde valga la pena trabajar de memoria.

Cómo se implementa de verdad

Aquí es donde se separa una app que pasa la auditoría de una que solo lo parece. El material que sigue es de Android; en iOS el equivalente es una clave del Secure Enclave con control de acceso biométrico, y el razonamiento es idéntico.

La biometría tiene que desbloquear una clave, no devolver un booleano

Si tu código hace «si la huella es correcta, entonces llama al endpoint», lo que tienes es una condición que se puede parchear en un dispositivo comprometido. El patrón correcto es pasar un CryptoObject al prompt: la operación criptográfica solo es posible tras una autenticación biométrica correcta.

generateSecretKey(KeyGenParameterSpec.Builder(
    KEY_NAME,
    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
    .setUserAuthenticationRequired(true)
    .setInvalidatedByBiometricEnrollment(true)
    .build())

biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher))

Se admiten Cipher, Signature, Mac y KeyAgreement.

Clase 3, no Clase 2

Android distingue BIOMETRIC_STRONG (Clase 3, el nivel de seguridad más alto según la definición de compatibilidad) de BIOMETRIC_WEAK (Clase 2). Para una app financiera, el requisito es Clase 3. Aceptar Clase 2 «para cubrir más dispositivos» es la clase de decisión que se descubre en la auditoría, no antes.

Autenticación por operación para importes altos

Se puede configurar una ventana temporal —autenticas una vez y la clave sirve durante N segundos— o exigir autenticación en cada operación, poniendo la duración a cero:

KeyGenParameterSpec.Builder("alias", keyPurpose)
    .setUserAuthenticationParameters(
        0, // 0 = por operación
        KeyProperties.AUTH_BIOMETRIC_STRONG or KeyProperties.AUTH_DEVICE_CREDENTIAL)
    .build()

La documentación es explícita sobre el caso de uso: operaciones de alto valor, donde cada una debe autorizarse expresamente. Y sobre una limitación que hay que conocer al diseñar: las claves con ventana temporal no pueden usar CryptoObject, porque permiten recurrir a la credencial del dispositivo y eso es incompatible con la vinculación criptográfica.

Traducción a producto: la sesión cómoda y la operación de dinero no pueden usar la misma clave. Son dos claves con dos políticas distintas.

El caso que rompe la experiencia si no lo previste

setInvalidatedByBiometricEnrollment(true) —el comportamiento por defecto— invalida la clave cuando el usuario da de alta una biometría nueva. Es correcto desde el punto de vista de seguridad: la clave estaba ligada a los datos biométricos anteriores.

Lo que provoca: alguien registra una huella más en su teléfono y, la próxima vez que entra en tu app, salta InvalidKeyException. Si no lo has manejado, el usuario ve un error incomprensible en su app del banco.

try {
    cipher.init(Cipher.ENCRYPT_MODE, secretKey)
} catch (e: InvalidKeyException) {
    // clave invalidada por alta de biometría: regenerar y volver a enrolar
    generateSecretKey(keySpec)
    biometricPrompt.authenticate(promptInfo)
}

Ese flujo de re-enrolamiento —con su comunicación al usuario— es parte del alcance, no un detalle.

Los tres fallos que suspenden una auditoría

  1. Biometría como booleano, sin CryptoObject. Es el más frecuente y el más grave.
  2. Aceptar Clase 2 por cobertura de dispositivos.
  3. No mostrar importe y beneficiario en la pantalla de aprobación. Sin eso no hay vinculación dinámica, y da igual lo bien que esté el resto.

Y uno de diseño que no es técnico: usar la misma sesión biométrica para entrar en la app y para firmar un pago. Cómodo, y exactamente lo que la independencia de elementos busca evitar.

Qué preguntar antes de estimar

  1. ¿Quién es el proveedor de autenticación: el core bancario del cliente, un tercero, o lo construimos?
  2. ¿Qué exenciones piensa aplicar el negocio y quién decide el análisis de riesgo?
  3. ¿Hay dispositivos gestionados de por medio? Si hay Acceso Condicional o MDM, el flujo de identidad cambia — está en SSO corporativo en una app móvil.
  4. ¿Qué pasa con los usuarios sin biometría disponible? Siempre hay un porcentaje, y su ruta alternativa también tiene que cumplir.
  5. ¿Quién audita, y contra qué guía?

Estas cinco decidan más del presupuesto que el número de pantallas.

Es el tipo de trabajo que hacemos en apps fintech: la parte que no se ve en las capturas y que decide si el proyecto pasa la revisión del banco.


Fuentes, consultadas el 14 de agosto de 2026: Reglamento Delegado (UE) 2018/389 y la documentación de Android sobre autenticación biométrica.