Análisis detallado de user Verification

En este documento, se analiza qué userVerification está en WebAuthn y los comportamientos del navegador que se generan cuando se especifica userVerification durante la creación de la llave de acceso o la autenticación.

¿Qué es la "verificación de usuario" en WebAuthn?

Las llaves de acceso se basan en criptografía de claves públicas. Cuando se crea una llave de acceso, se genera un par de claves públicas y privadas, el proveedor de llaves de acceso almacena la clave privada y la clave pública se devuelve al servidor del usuario de confianza (RP) para que la almacene. El servidor puede autenticar a un usuario verificando una firma con la misma llave de acceso usando la clave pública vinculada. La marca "usuario presente" (UP) en una credencial de clave pública demuestra que alguien interactuó con el dispositivo durante la autenticación.

La verificación del usuario es una capa opcional de seguridad que busca confirmar que, durante la autenticación, estuvo presente la persona correcta, no solo una persona, como lo afirma la presencia del usuario. En los smartphones, esto suele hacerse mediante el mecanismo de bloqueo de pantalla, ya sea un método biométrico o un PIN o una contraseña. Si se realizó la verificación del usuario, se informa en la marca "UV" que se muestra en los datos del autenticador durante el registro y la autenticación de la llave de acceso.

Captura de pantalla de un diálogo de verificación de usuario del llavero de iCloud en macOS El diálogo le solicita al usuario que acceda con Touch ID y muestra el origen que solicita la autenticación y el nombre de usuario. En la parte superior derecha del diálogo, hay un botón con la etiqueta "Cancelar".
Diálogo de verificación del usuario en el llavero de iCloud en macOS
Captura de pantalla de un diálogo de verificación de usuario en Chrome para Android. El diálogo le solicita al usuario que verifique su identidad mediante el reconocimiento facial o la detección de huella dactilar y muestra el origen que solicita la autenticación. En la esquina inferior izquierda, hay una opción para verificar con un PIN.
Diálogo de verificación del usuario en Android Chrome.

Cómo se validan UP y UV en el servidor

Las marcas booleanas de presencia del usuario (UP) y del usuario verificado (UV) se le indican al servidor en el campo de datos del autenticador. Durante la autenticación, el contenido del campo de datos del autenticador se puede validar verificando la firma con la clave pública almacenada. Siempre que la firma sea válida, el servidor puede considerar que las marcas son genuinas.

Representación de la estructura de datos de autenticación. De izquierda a derecha, cada sección de la estructura de datos dice "RP ID HASH" (32 bytes), "FLAGS" (1 byte), "COUNTER" (4 bytes, big-endian uint32), "ATTESTE CRED. DATA' (longitud variable si está presente) y 'EXTENSIONS' (longitud variable si está presente [CBOR]). La sección "FLAGS" se expande para mostrar una lista de posibles marcas, etiquetadas de izquierda a derecha: "ED", "AT", "0", "BS", "BE", "UV", "0" y "UP").
Campos de datos del Autenticador en una credencial de clave pública.

En el registro y la autenticación de la llave de acceso, el servidor debe examinar que la marca UP es true y si la marca UV es true o false, según el requisito.

Especifica el parámetro userVerification

Según la especificación de WebAuthn, el RP puede solicitar una verificación del usuario con un parámetro userVerification tanto en la creación como en la aserción de credenciales. Acepta 'preferred', 'required' o 'discouraged', que significan respectivamente:

  • 'preferred' (predeterminado): Es preferible usar un método de verificación del usuario en el dispositivo, pero se puede omitir si no está disponible. La credencial de respuesta contiene un valor de marca UV de true si se realizó la verificación del usuario y de false si no se realizó la UV.
  • 'required': Se requiere invocar un método de verificación del usuario disponible en el dispositivo. Si no hay una disponible, la solicitud falla de forma local. Esto significa que la credencial de respuesta siempre se muestra con la marca UV establecida en true.
  • 'discouraged': No se recomienda usar un método de verificación de usuarios. Sin embargo, según el dispositivo, la verificación del usuario se puede realizar de todas formas, y la marca UV puede contener true o false.

Código de muestra para crear llaves de acceso:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

Código de muestra para la autenticación con llave de acceso:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

¿Qué opción deberías elegir para userVerification?

El valor de userVerification que debes usar depende de los requisitos de tu aplicación y de las necesidades de la experiencia del usuario.

Cuándo usar userVerification='preferred'

Usa userVerification='preferred' si priorizas la experiencia del usuario sobre la protección.

Hay entornos en los que la verificación de usuarios supone más inconvenientes que la protección. Por ejemplo, en macOS, en los que Touch ID no está disponible (porque el dispositivo no es compatible, está inhabilitado o está en modo clamshell), se le pedirá al usuario que ingrese la contraseña del sistema. Esto genera inconvenientes y es posible que el usuario abandone por completo la autenticación. Si eliminar los inconvenientes es más importante para ti, usa userVerification='preferred'.

Captura de pantalla de un diálogo de llave de acceso en macOS que aparece cuando Touch ID no está disponible El diálogo contiene información como el origen que solicita la autenticación y el nombre de usuario. En la parte superior derecha del diálogo, hay un botón con la etiqueta "Cancelar".
Se muestra un diálogo de llave de acceso en macOS cuando Touch ID no está disponible.

Con userVerification='preferred', la marca UV es true si la verificación del usuario se realiza correctamente y false si se omite. Por ejemplo, en macOS, donde Touch ID no está disponible, le pide al usuario que haga clic en un botón para omitir la verificación del usuario, y la credencial de clave pública incluye una marca UV false.

La marca UV puede ser una señal en tu análisis de riesgos. Si el intento de acceso parece riesgoso debido a otros factores, es posible que desees presentar verificaciones de acceso adicionales al usuario si no se realizó la verificación.

Cuándo usar userVerification='required'

Usa userVerification='required' si crees que las teclas UP y UV son absolutamente necesarias.

Una desventaja de esta opción es que el usuario podría experimentar más inconvenientes al acceder. Por ejemplo, en macOS donde Touch ID no está disponible, se le pide al usuario que ingrese la contraseña del sistema.

Con userVerification='required', puedes asegurarte de que la verificación del usuario se realice en el dispositivo. Asegúrate de que el servidor verifique que la marca UV sea true.

Conclusión

Al aprovechar la verificación del usuario, las partes que confían en las llaves de acceso pueden medir la probabilidad de que acceda el propietario del dispositivo. Tú deciden si exigir la verificación del usuario o hacerla opcional según la importancia que tenga el mecanismo de acceso de resguardo en el flujo de usuarios. Asegúrate de que el servidor verifique la marca UP y la marca UV para la autenticación del usuario de la llave de acceso.