En este documento, se analiza qué es userVerification
en WebAuthn y los comportamientos del navegador que se generan cuando se especifica userVerification
durante la creación o autenticación de la llave de acceso.
¿Qué es la "verificación del 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/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 su almacenamiento. El servidor puede autenticar a un usuario verificando una firma firmada por la misma llave de acceso usando la clave pública vinculada. El «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 de seguridad opcional que busca confirmar que la persona correcta estuvo presente durante la autenticación, 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, un PIN o una contraseña. Si se realizó la verificación del usuario, se informa en el campo "UV" marca que se muestra en los datos del autenticador durante el registro y la autenticación de la llave de acceso
Cómo se validan UP y UV en el servidor
Las marcas booleanas de presencia del usuario (UP) y verificadas por el usuario (UV) se señalan 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.
En el registro y la autenticación de la llave de acceso, el servidor debe examinar que la marca UP sea 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 lo siguiente:
'preferred'
(predeterminado): Se prefiere 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 detrue
si se realizó la verificación del usuario yfalse
si no se realizó 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 manera local. Esto significa que la credencial de respuesta siempre se muestra con la marca UV establecida entrue
.'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 contenertrue
ofalse
.
Código de muestra para la creación de 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 elegirías para userVerification
?
El valor userVerification
que debes usar depende de los requisitos de tu aplicación y 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 los usuarios es más difícil que la protección. Por ejemplo, en macOS, donde Touch ID no está disponible (porque el dispositivo no es compatible, está inhabilitado o el dispositivo está en modo clamshell), se le solicita al usuario que ingrese su contraseña del sistema. Esto genera inconvenientes, y es posible que el usuario abandone por completo la autenticación. Si eliminar la fricción es más importante para ti, usa userVerification='preferred'
.
Con userVerification='preferred'
, la marca UV es true
si se realiza correctamente la verificación del usuario y false
si se omite la verificación del usuario. Por ejemplo, en macOS, donde Touch ID no está disponible, le solicita 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, puedes presentarle desafíos de acceso adicionales al usuario en caso de que no se haya realizado la verificación del usuario.
Cuándo usar userVerification='required'
Usa userVerification='required'
si crees que tanto UP como UV son absolutamente necesarios.
Una desventaja de esta opción es que es posible que el usuario experimente más inconvenientes a la hora de acceder. Por ejemplo, en macOS, cuando Touch ID no está disponible, se le solicita al usuario que ingrese su 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
Con la verificación del usuario, las partes que dependen de llaves de acceso pueden medir las probabilidades de que el propietario del dispositivo acceda. Usted decide si exigir la verificación del usuario o hacerlo opcional según la importancia del 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.