Desafío desafiante: el hashing de la contraseña del lado del cliente y la verificación de la contraseña del lado del servidor

13

Tenemos un sitio web donde los usuarios necesitan iniciar sesión para acceder a información privilegiada. Obviamente, estamos utilizando SSL, pero también quiero evitar que las contraseñas de texto sin formato terminen accidentalmente en los registros del servidor o en los ojos errantes de los administradores. Por lo tanto, quiero implementar el hashing del lado del cliente utilizando Javascript.

Además, quiero evitar revelar parejas de usuarios con contraseñas idénticas, por lo tanto, use un salt específico del usuario. Por último, me gustaría agregar un desafío aleatorio (también conocido como nonce) en la mezcla para garantizar que un interceptor * no pueda usar el hash final como la nueva "contraseña". Haré un viaje de ida y vuelta adicional al servidor web para obtener el salt y el desafío antes de iniciar el hashing de contraseñas. *) Sí, estamos usando SSL, pero como defensa en profundidad, me gustaría que la implementación sea lo más sólida posible.

Especialmente el desafío es un reto. La única implementación factible que conozco es primero calcular el hash de la contraseña final (usando bcrypt, scrypt o PBKDF2) y luego hacer una ronda sha256_hmac adicional usando el desafío. En el lado del servidor, obtenemos el hash de contraseña de la base de datos, realizamos el mismo sha256_hmac adicional y comparamos el resultado.

Sin embargo, lo anterior implicaría que el cálculo de hash de la contraseña completa debe realizarse en el lado del cliente en Javascript, porque el hashing en el desafío siempre debe ser el último paso. En un iPhone 3G heredado (?), Solo se pueden realizar 6 rondas de cifrado, o 5000 rondas de PBKDF2-SHA256 en 2 segundos, que es el retraso máximo que podemos tolerar.

Pregunta # 1: ¿Estoy en lo cierto al afirmar que en la actualidad bcrypt debería ser de al menos 12 rondas, y PBKDF2-SHA256 al menos 5000 rondas? ¿Entonces debo elegir las 5000 rondas de PBKDF2-SHA256?

Pregunta n. ° 2: ¿Existen mecanismos de respuesta-desafío que puedan operar antes en el proceso (por ejemplo, con una contraseña de hash), por lo que puedo dejar el endurecimiento de bcrypt / PBKDF2 al servidor web?

Pregunta # 3: Suponiendo que no exista tal mecanismo de desafío-respuesta, ¿es mejor abandonar mi requisito de desafío-respuesta y solo aplicar un lado del cliente de sal específico del usuario y hacer un endurecimiento completo del lado del servidor? ¿Resultaría eso en un sistema más sólido en general que el uso de un mecanismo de desafío-respuesta y menos rondas?

EDITAR: Para resumir el largo camino de comentarios a continuación sobre la seguridad del hashing del lado del cliente en general: la opinión general parece ser que la complejidad agregada no vale la pena y es mejor esforzarse en auditar el servidor. Código lateral y acceso limitado al servidor para personal no confiable.

    
pregunta Jason Smith 12.07.2012 - 15:28
fuente

4 respuestas

11

Creo que estás perdiendo el tiempo y agregando complejidad innecesaria. No creo que las razones que usted da sean suficientes para garantizar este tipo de mecanismo de hashing de contraseña del lado del cliente.

En cambio, sugiero que sea sencillo. Enviar la contraseña a través de un enlace cifrado SSL. Cuando se trata de seguridad, lo simple es bueno. La complejidad innecesaria es el enemigo de la seguridad, porque presenta la oportunidad de errores y errores.

Ahorre energía para otras tareas de seguridad que abordarán amenazas más realistas. Hay una cantidad limitada de tiempo, energía y presupuesto que uno puede gastar en mejorar la seguridad; mejor gastarlo en los lugares que produzcan la mayor inversión del dinero (la mayor mejora en seguridad, dada la inversión). Creo que encontrará que hay otras maneras en que podría gastar su refuerzo de su sistema que mejorará la seguridad aún más.

Si le preocupa si el código del lado del servidor está manejando la contraseña de manera adecuada, entonces revise ese código con cuidado: debe estar contenido dentro de una porción muy pequeña de código. Esto debería hacerse cargo de riesgos como, por ejemplo, el servidor que registra las contraseñas de texto claro: simplemente lee todas las líneas de código involucradas en la verificación de contraseñas o que lee la contraseña, asegúrese de que lo primero que hace es copiar la contraseña de manera apropiada y Asegúrese de que todo lo que hace es verificar la validez de la contraseña y devolver verdadero o falso. Si su sistema está bien diseñado, esto debería ser bastante sencillo de verificar a través de la revisión del código. Si el código no está bien diseñado, quizás ahora sea un buen momento para solucionarlo.

    
respondido por el D.W. 16.07.2012 - 01:06
fuente
6

Si aún no lo ha hecho, es posible que desee examinar SRP. Debería cumplir con todos sus requisitos, si desea un sistema de tipo de desafío / respuesta.

enlace

    
respondido por el broadway 12.07.2012 - 22:16
fuente
4

Me gustaría desconfiar de cualquier protocolo de elaboración casera. También desconfiaría de cualquier protocolo de autenticación basado en hashing del lado del cliente. Su mejor opción es estudiar Autenticación NTLM y el NÚMERO GRANDE de los ataques contra este protocolo. Como la vulnerabilidad débil de NTLM .

(SRP no es malo, SRP-TLS se ve muy bien)

    
respondido por el rook 14.07.2012 - 22:07
fuente
1
  1. No, todavía eres demasiado pequeño. La hoja de referencia de almacenamiento de contraseñas de OWASP recomienda 64,000 iteraciones PBKDF2 en 2012 y las duplica cada 2 años (https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet).

  2. Vea las otras respuestas anteriores.

  3. Usted tiene la opción de hacer un hashing del lado del cliente (por ejemplo, 2,000 rondas PBKDF2_SHA-1), y luego una vez que el resultado llega al servidor, ejecútelo a través de otro conjunto grande de hashing (por ejemplo, , 300,000 rondas de PBKDF2_SHA-512), y compare ese valor final.

Su base de datos almacena solo el valor final de PBKDF2 doble.

Sus archivos de registro web y / o las posibles sesiones de SSL débiles utilizan el valor intermedio único PBKDF2. Si bien ese valor intermedio es ciertamente mucho, mucho más débil que el valor final, todavía es mucho más fuerte que el texto claro.

Tenga en cuenta que también debe verificar las contraseñas que los usuarios proponen al cambiar su contraseña / seleccionar una nueva contraseñas con un diccionario de descifrado normal con algunas reglas (en minúsculas para eliminar los juegos de caso, agregue números del 1 al 1000 después de la palabra, agregue fechas) después de una palabra, las traducciones básicas de 1337 hablan, etc.) para evitar la contraseña "segura" "P @ $$ w0rd" (mayúsculas, minúsculas, símbolos y números, de 8 caracteres, ¡debe ser realmente fuerte!) de apareciendo.

    
respondido por el More than one round of PBKDF2 02.11.2012 - 20:50
fuente

Lea otras preguntas en las etiquetas