¿Vale la pena cifrar contraseñas en el lado del cliente?

Resuelto Zakaria asked hace 14 años • 13 respuestas

Cuando quiero implementar un sistema de inicio de sesión, siempre comparo el MD5 de la contraseña dada con su valor en la tabla de usuarios en el lado del servidor.

Sin embargo, un amigo mío me dijo que un software de red podía detectar una contraseña "clara".

Entonces mi pregunta es: ¿es una buena idea cifrar la contraseña en el lado del cliente? ¿Es mejor que aplicar hash en el lado del servidor?

Zakaria avatar Sep 15 '10 15:09 Zakaria
Aceptado

Básicamente, tu amigo tiene razón. Pero simplemente codificar la contraseña en el lado del cliente es apenas mejor que enviarla como texto sin formato al servidor. Alguien que pueda escuchar sus contraseñas de texto sin formato también podrá escuchar las contraseñas con hash y utilizar estos hashes capturados para autenticarse en su servidor.

En este sentido, los protocolos de autenticación más seguros generalmente pasan por una serie de obstáculos para asegurarse de que un ataque de repetición de este tipo no pueda funcionar, generalmente permitiendo al cliente seleccionar un montón de bits aleatorios, que se codifican junto con la contraseña. , y también enviado sin cifrar al servidor.

En el servidor:

  • generar algunos bits aleatorios
  • enviar estos bits (en texto claro) al cliente

Sobre el cliente:

  • generar algunos bits aleatorios
  • concatenar contraseña, los bits aleatorios del servidor y los bits aleatorios del cliente
  • generar hash de lo anterior
  • enviar bits aleatorios (en texto claro) y hash al servidor

Como el servidor conoce su propia información aleatoria así como los bits aleatorios del cliente (los obtuvo como texto claro), puede realizar esencialmente la misma transformación. Este protocolo garantiza que nadie que escuche esta conversación pueda utilizar la información posteriormente para autenticarse falsamente utilizando la información registrada (a menos que se haya utilizado un algoritmo muy débil...), siempre y cuando ambas partes generen diferentes "bits de ruido" cada vez. Se realiza el apretón de manos.

Editar Todo esto es propenso a errores, tedioso y algo difícil de hacer bien (léase: seguro). Si alguna vez es posible, considere usar implementaciones de protocolos de autenticación ya escritas por personas con conocimientos (¡a diferencia de mí! Lo anterior es solo de memoria de un libro que leí hace algún tiempo). Por lo general, no querrás escribir esto tú mismo.

Dirk avatar Sep 15 '2010 08:09 Dirk

En primer lugar, esto NO mejora la seguridad de su aplicación (suponiendo que sea una aplicación web).

Utilice SSL (o en realidad TLS, que comúnmente se llama SSL). Es gratis y fácil de configurar con Certbot .

El por qué de esto es simple. TLS resuelve un problema (cuando se usa con un certificado de una autoridad certificadora, no autofirmado) que es bastante grande en criptografía: ¿Cómo sé que el servidor con el que estoy hablando es el servidor con el que creo que estoy hablando? Los certificados TLS son una forma de decir: "Yo, la autoridad certificadora, en la que su navegador confía, certifica que el sitio web en [url] tiene esta clave pública, con una clave privada correspondiente, que (clave privada) solo conoce el servidor, mire Puse mi firma en todo el documento, si alguien la alteró se puede ver".

Sin TLS, cualquier cifrado se vuelve inútil, porque si me siento a tu lado en una cafetería, puedo hacer que tu computadora portátil/teléfono inteligente piense que soy el servidor y MiTM (Man in The Middle) tú. Con TLS, su computadora portátil/teléfono inteligente gritará "CONEXIÓN NO CONFIABLE", porque no tengo un certificado firmado por una autoridad certificadora que coincida con su sitio. (Cifrado versus autenticación).

Descargo de responsabilidad: los usuarios tienden a hacer clic en estas advertencias: "¿Conexión no confiable? ¿Qué? ¡Solo quiero mis fotos de gatitos! Agregar excepción Haga clic en Confirmar Haga clic en ¡YAY! ¡Gatitos!"

Sin embargo, si realmente no desea utilizar un certificado, aún así DEBE implementar el hash de Javascript del lado del cliente (y use la biblioteca de Stanford (SJCL) para eso, NUNCA IMPLEMENTE CRYPTO USTED MISMO ).

¿Por qué? ¡Reutilización de contraseña! Puedo robar tu cookie de sesión (que me permite fingir ante tu servidor que soy tú) sin HTTPS fácilmente (ver Firesheep). Sin embargo, si agrega Javascript a su página de inicio de sesión que, antes de enviar, codifica su contraseña (use SHA256, o mejor aún, use SHA256, envíeles una clave pública que usted generó y luego cifre la contraseña con esa contraseña, no puede usar un salt con this), y luego envía la contraseña cifrada/hash al servidor. REHASH el hash en su servidor con una sal y compárelo con lo que está almacenado en su base de datos (almacene la contraseña de esta manera:

(SHA256(SHA256(password)+salt))

(guarde también el salt como texto sin formato en la base de datos)). Y envía tu contraseña así:

RSA_With_Public_Key(SHA256(password))

y verifica tu contraseña así:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Porque, SI alguien está husmeando a su cliente, podrá iniciar sesión como su cliente (secuestro de sesión) pero NUNCA verá la contraseña en texto plano (a menos que altere su Javascript. Sin embargo, un hacker de Starbucks probablemente no sabrá cómo o no estará interesado). en esto.) Por lo tanto, obtendrán acceso a su aplicación web, pero no a su correo electrónico/Facebook/etc. (para lo cual sus usuarios probablemente usarán la misma contraseña). (La dirección de correo electrónico será su nombre de inicio de sesión o se encontrará en su perfil/configuración en su aplicación web).

FriendlyCryptoNeighbor avatar May 09 '2014 20:05 FriendlyCryptoNeighbor

En realidad, no estoy de acuerdo con que el hash del lado del cliente sea más seguro en este caso. Creo que es menos seguro.

El objetivo de almacenar un hash de la contraseña en su base de datos en lugar de la contraseña real (o incluso una contraseña cifrada) es que es matemáticamente imposible obtener la contraseña original a partir de un hash (aunque teóricamente es posible obtener una contraseña en colisión). entrada hash, cuya dificultad depende de la seguridad del algoritmo hash). El posible vector de ataque aquí es que si un atacante potencial de alguna manera comprometiera su base de datos de almacenamiento de contraseñas, aún así no podría obtener las contraseñas originales de sus usuarios.

Si su mecanismo de autenticación envía un hash de la contraseña, entonces en el escenario de "violación de seguridad" (es decir, el atacante de alguna manera obtuvo una copia de su base de datos de contraseñas), el atacante no necesita conocer la contraseña real; simplemente envía la contraseña hash que obtuvieron de la infracción y listo, tienen acceso a la cuenta de ese usuario. ¡Esto anula por completo el objetivo de almacenar una contraseña hash en primer lugar!

La forma realmente segura de hacerlo es enviar al cliente una clave pública única para que cifre la contraseña, luego usted la descifra y la vuelve a codificar en el lado del servidor.

Por cierto, este tipo de preguntas probablemente obtendrán respuestas de más expertos en Security StackExchange.

Adam Burley avatar Jan 17 '2014 09:01 Adam Burley

Probablemente esté bien no preocuparse por esto, como menciona Dirk, incluso si codifica las contraseñas, un usuario malintencionado podría estar en una red y ver cómo se envía el hash, y simplemente podría enviar el mismo hash ellos mismos.

Es un poco mejor, ya que evita que el usuario malintencionado sepa cuál es la contraseña, pero como aún puede iniciar sesión (o potencialmente reconstruir la contraseña original ), eso no es tan útil.

En general, si le preocupa la seguridad de las contraseñas y los datos de sus usuarios (¡y debería estarlo!), querrá utilizar un servidor SSL seguro. Si esto no le preocupa por cualquier motivo, es mejor que no se moleste con el hash; es sólo seguridad a través de la oscuridad .


Edición de agosto de 2014: Google está presionando cada vez más para que los sitios web cambien a HTTPS en todas partes , porque proteger la comunicación en sí es la única forma de evitar ataques de rastreo de redes. Los intentos de ofuscar los datos transmitidos sólo obstaculizarán, no detendrán, a un atacante dedicado, y pueden dar a los desarrolladores una peligrosa y falsa sensación de seguridad.

dimo414 avatar Sep 15 '2010 08:09 dimo414