¿Desafío SRP o WebCrypto?

3

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?

    
pregunta lakano 25.10.2017 - 20:01
fuente

1 respuesta

0

Propongo esta solución para responder a mi pregunta:

Las claves ECDSA de WebCrypto son realmente útiles, pero si las usamos como se explica en mi pregunta (encriptada con AES-GCM), es posible que un JS Coder vaya al navegador de la víctima e intente miles de contraseñas en la consola JS Se sabe si es la buena contraseña o no, sin ninguna conexión al servidor. Por lo tanto, seguramente es mejor no permitir la contraseña sin la interacción del servidor. Es por eso que mi solución es mantener solo las claves ECDSA del dispositivo, con una clave privada no extraíble, no encriptada y global para todos los usuarios en este dispositivo.

El SRP se ha probado y desplegado ampliamente, sin embargo, en el caso de una pérdida en la base de datos, incluso si es difícil recuperar la contraseña del usuario de la fuerza bruta, es posible porque el atacante tiene la sal del SRP y el verificador. Por lo tanto, lo mejor es no usar la contraseña del usuario sino una OTP aleatoria y renovarla con cada conexión exitosa.

Primero, si el dispositivo no tiene una clave privada almacenada:

  • Generar nuevas claves de ECDSA de WebCrypto
  • Enviar la clave pública de este dispositivo al servidor
  • El servidor devuelve un deviceUUID y una especie de JWT para las próximas solicitudes

Cuando el usuario se registra o autoriza un nuevo dispositivo:

  • Generar una OTP de 512 bits aleatorios
  • Genere una sal de 128 bits aleatorios para la OTP derivada
  • Derive el OTP con Argon2 512 bits, salt = derivadoOTPSalt
  • Genere una sal de 128 bits aleatorios para el SRP
  • Cree el verificador de SRP para esta clave de POT derivada
  • Si el usuario tiene un dispositivo U2F, regístrelo para este dispositivo
  • Envíe al servidor el deviceUUID, SRP salt / verifier de la claveOTP derivada y la clave pública de U2F. La solicitud se firma con la clave privada del dispositivo ECDSA.
  • Si el servidor acepta el registro de usuarios, solicite una contraseña para este dispositivo
  • Genere una sal de 128 bits aleatorios para la derivación de contraseña
  • Derive la contraseña de usuario con Argon2 512 bits, salt = DerivadoPasswordSalt
  • Cree una clave enmascarada: OTP ^ derivadoPassword (XOR)
  • Guardamos en una base de datos dedada por el usuario. IndexedDB / sha256 (inicio de sesión): maskedKey, derivadoOTPSalt, derivadoPasswordSalt, u2f = (verdadero / falso)

Luego, cuando el usuario quiera iniciar sesión:

  • Envíe inicio de sesión y deviceUUID al servidor y solicite desafíos SRP / U2F (solicitud firmada por la clave privada ECDSA, como todas las solicitudes al servidor)
  • Si la firma del dispositivo es correcta, el servidor devuelve: challengeUUID, SRP Salt / B challenge y un desafío de texto aleatorio para firmar con el dispositivo U2F (incluso si sabemos que el usuario no tiene uno)
  • Si el usuario tiene un dispositivo U2F, firme el desafío o genere bits aleatorios (para engañar a cualquier MITM)
  • Solicite la contraseña de usuario para este dispositivo y derívela (Argon2, salt = drawnPasswordSalt)
  • Obtenga el resultado de la clave enmascarada almacenada ^ Derivada de contraseña del usuario (XOR)
  • A partir de este resultado (en teoría, obtenemos la OTP original), luego lo derivamos con Argon2 / salt = derivaOTPSalt, y creamos a partir de esto la respuesta de desafío A / M1 SRP
  • También preparamos la siguiente OTP siguiendo el método de registro
  • Enviar al servidor: challengeUUID, desafío U2F, desafío SRP A / M1 y el siguiente verificador de SRP & Sal para la próxima OTP.

El servidor puede confirmar que es la buena OTP, la buena firma del dispositivo ECDSA y, si el usuario tiene un dispositivo U2F, la buena firma U2F. Si todo está bien, el servidor reemplazará el antiguo verificador / sal OTP con el siguiente y devolverá una nueva autorización JWT.

Con esta solución, incluso si se ha filtrado la base de datos, es imposible recuperar la contraseña de usuario real, solo es posible recuperar la OTP derivada, y no es suficiente que el atacante falsifique la identidad del usuario porque también necesita la clave privada del dispositivo (y un posible dispositivo U2F).

Para un MITM, no puede leer la contraseña de usuario ni la OTP, pero puede leer cada verificador / sal de OTP. De lo contrario, no es suficiente porque él también necesita la clave del dispositivo privado y puede ser el dispositivo U2F del usuario. También utilizamos HTTPS con HSTS + HPKP para prevenir ataques MITM.

Para un atacante con acceso al dispositivo de la víctima, puede usar la clave privada del dispositivo y puede leer las sales y la clave enmascarada, pero esto no debería ayudar a adivinar la contraseña, incluso con ataques de fuerza bruta en el lado del cliente. , porque necesita verificar si la OTP está bien con una solicitud del servidor.

Esta solución también se reinicia cada vez que se realiza una OTP nueva después de cada autenticación exitosa. En caso de pérdida de la base de datos, podemos enviar una notificación PUSH a todos los usuarios para pedirles que se conecten al servicio, para restablecer su OTP.

Por lo tanto, esta solución utiliza protocolos respetados (SRP, claves de dispositivo ECDSA, verificación U2F, OTP, Argon2 / PBKDF2) y se mezclan para aumentar la seguridad.

Si algún par podría revisar este diseño para señalar cualquier punto de falla, esto podría ser realmente apreciado :)

    
respondido por el lakano 28.10.2017 - 13:47
fuente

Lea otras preguntas en las etiquetas