Para un nuevo sitio web (HTTPS con HSTS + HPKP), nos gustaría restringir el acceso de inicio de sesión solo en los dispositivos de usuarios autorizados. Para eso, hay un WebCrypto ECDSA de claves públicas / privadas generadas en cada nuevo dispositivo. El servidor almacena la clave pública del nuevo dispositivo y devuelve una ID de dispositivo. El navegador guarda en un IndexedDB llamado «dispositivo» la clave privada (no extraíble) y la ID del dispositivo.
Cuando el usuario registra su cuenta o desea autorizar un nuevo dispositivo, le pedimos una contraseña para este dispositivo, pero no queremos guardar su contraseña en la base de datos del servidor.
-
Podríamos usar el protocolo SRP y enviar el archivo salt & «Verificador» al servidor, pero más bien utilizando la contraseña del usuario, usamos una contraseña derivada (biblioteca WebCrypto PBKDF2 o Argon2)
-
O podríamos usar WebCrypto nuevamente para crear nuevas claves ECDSA, específicas para este usuario en este dispositivo, y enviar la clave pública en el servidor. En el navegador, almacenamos en un IndexedDB llamado «base64 (SHA-256 (inicio de sesión)» esta clave privada de usuario pero encriptada (función wrapKey) con el algoritmo AES-GCM y para la clave usamos la derivación de contraseña de usuario (WebCrypto PBKDF2 o Argon2 biblioteca externa). Luego, para iniciar sesión, el servidor envía un desafío, una cadena aleatoria simple, el cliente devuelve la firma de este desafío con esta nueva clave privada específica del usuario (por lo que debe conocer la contraseña correcta para desenvolver la clave). / p>
Si se filtra nuestra base de datos:
-
Con SRP, el verificador no puede permitir adivinar fácilmente la contraseña del usuario, pero supongo que debemos solicitar una nueva contraseña a todos nuestros usuarios.
-
Con WebCrypto, solo es una clave pública. Los usuarios no necesitan cambiar su contraseña. EDITAR: un inconveniente es que es posible realizar varias comprobaciones de contraseñas en el lado del cliente, por ejemplo, si supiera que mi víctima podría intentar, podría haber 1000 contraseñas posibles en la consola JS para desenvolver la clave privada del usuario, sin la necesidad de contactar al servidor .
Por supuesto, si los IndexedDBs se eliminan en el navegador, esto requiere que el usuario inicie un proceso para recuperar su cuenta (pregunta privada, OTP por correo electrónico, lo que sea ... no es el tema), pero esto no es específico para la opción WebCrypto, también es compatible con la opción SRP porque necesitamos detectar la ID del dispositivo y verificar su firma para asegurarnos de que sea un dispositivo autorizado por el usuario.
Solo para información, también agregamos U2F después de este primer desafío de autenticación.
En mi caso específico, ¿recomienda utilizar el desafío SRP o este desafío WebCrypto, por favor?