2010-09-15 13 views
85

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

Sin embargo, un amigo me dijo que una contraseña "clara" podría ser olfateada por un software de red.

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

+1

Estaba pensando en hash de la contraseña en el cliente, pero sólo por lo que puede estar seguro de la contraseña del cliente nunca existe como texto en el lado del servidor, lo que significa que pueden sentirse más tranquilos al saber que no sé su real contraseña, o no puede renunciar fácilmente si está comprometida. ¿estoy loco? – Cyclone

+1

simplemente para la corrección, ya que estamos hablando de seguridad, y MD5 se mencionó en el PO: [. Uno siempre debe usar una sal al cifrar una contraseña] (http: // stackoverflow.com/questions/420843/how-do-password-salt-help-against-a-rainbow-table-attack) Usar MD5 sin sal plana es simplemente marginalmente mejor que almacenar contraseñas de texto claro en su base de datos. – sffc

+1

@Cyclone Hashing SÓLO en el lado del cliente es definitivamente una mala idea, ya que si el atacante conoce de alguna manera el hash, puede usarlo para iniciar sesión como si conociera la contraseña, evitando el código hash del lado del cliente. – Teejay

Respuesta

84

Básicamente, su amigo tiene razón. Pero simplemente hash la contraseña en el lado del cliente es solo solo mejor que enviarlo como texto sin formato al servidor. Alguien que puede escuchar sus contraseñas de texto sin formato también es capaz de escuchar las contraseñas hash, y usar estos hashes capturados para autenticarse contra su servidor.

En este caso, los protocolos de autenticación más seguros generalmente pasan por varios aros para asegurarse de que ese ataque de repetición no puede funcionar, normalmente, al permitir al cliente seleccionar un montón de bits aleatorios, que son hash junto con la contraseña, y también enviado en claro al servidor.

En el servidor:

  • generan unos pocos bits de azar
  • enviar estos bits (en texto claro) al cliente

En el cliente:

  • generar algunos bits aleatorios
  • concatenar contraseña, el ser bits aleatorios de VER y el cliente bits aleatorios
  • generan hash de la anterior
  • enviar datos al azar (en texto claro) y el hash al servidor

Como el servidor conoce su propia información al azar, así como la bits aleatorios del cliente (los obtuvo como texto claro), puede realizar esencialmente la misma transformación. Este protocolo asegura que nadie que esté escuchando en esta conversación pueda usar la información más tarde para autenticarse falsamente usando la información grabada (a menos que se use un algoritmo muy débil ...), siempre y cuando ambas partes generen diferentes "bits de ruido" cada vez, el apretón de manos se realiza.

Editar Todo esto es propenso a errores y tedioso y algo difícil de conseguir a la derecha (léase: seguro). Si alguna vez es posible, considere usar implementaciones de protocolos de autenticación ya escritas por personas conocedoras (¡a diferencia de mí! Lo anterior es solo de la memoria de un libro que leí hace algún tiempo). Realmente no desea escribir esto usted mismo normalmente.

+2

¿Cómo se puede autenticar con la contraseña hash en el sistema de inicio de sesión dado que se procesará el hash nuevamente? – Zakaria

+4

Si almacena sus contraseñas en forma de hash en el servidor (como debería), el cliente tendrá que usar la contraseña dos veces: primero, la contraseña sola, para que coincida con la vista del mundo del servidor y luego como se describió anteriormente por el bien del protocolo. – Dirk

+2

@Dirk, ya que el atacante puede olfatear en ambos sentidos, los "bits aleatorios" serían olfateados. Luego, el atacante puede analizar (leer: fuerza bruta) el par de solicitudes y respuestas fuera de línea para encontrar la contraseña original. – Pacerier

14

Es probable que no se preocupe por esto, ya que Dirk menciona incluso si tiene las contraseñas que un usuario malicioso podría tener en una red y ve que se envía el hash, y simplemente puede enviar el mismo hash.

Es ligeramente mejor, ya que evita que el usuario malicioso de saber cuál es la contraseña, pero ya que todavía pueden conectarse (o potencialmente reconstruct the original password), eso no es tan útil.

En general, si le preocupa la seguridad de las contraseñas y los datos de su usuario (¡y debería estarlo!), Querrá usar un servidor SSL seguro. Si esto no es una preocupación para usted por la razón que sea, es mejor que no se moleste con hashing; es solo security through obscurity.


Editar Ago 2014: Google está presionando cada vez más fuerte para los sitios web a switch to HTTPS everywhere, debido a que conseguir la comunicación en sí misma es la única manera de prevenir los ataques de red sniffing. Los intentos de ofuscar los datos transmitidos solo obstaculizarán, no detendrán, a un atacante dedicado, y pueden dar a los desarrolladores una falsa sensación de seguridad peligrosa.

+17

Los comentarios son bienvenidos, los votos ocultos no ayudan a nadie. – dimo414

1

que he estado haciendo mucho trabajo en este recientemente, IRL hay dos problemas con picadillo lado del cliente/ simétrico de cifrado con muy matar la idea: 1. Tienes que devolver la sal al servidor DE ALGUNA MANERA ... y para encriptarla del lado del cliente, necesitarías una contraseña ... lo que frustraría el propósito. 2. Expone su implementación de hashing (no es un gran problema ya que la mayoría de los sitios usan uno de 3 o 4 alias de hash) lo que hace que el ataque sea más fácil (solo necesita probar uno en lugar de n).

Lo que finalmente llegué fue un cifrado asimétrico en el cliente que usa OpenPGP.js o similar ... Esto depende de una clave importada o generada del lado del cliente en el cliente y del servidor que la envía. Solo la clave pública del cliente puede enviarse nuevamente al servidor. Esto protege contra los ataques MIM y es tan seguro como el dispositivo (actualmente almaceno la clave privada del cliente por defecto en localStore, es una demostración).

La gran ventaja de esto es que no tengo que han almacenado datos de los usuarios/incluso en la memoria sin cifrar en mi tienda/servidor de datos (y la clave privada de mi servidor está físicamente separado)

La base de esta era proporcionar a las personas una forma de comunicarse de forma segura donde HTTPS estaba restringido (p. ej., Irán/Corea del Norte atc ...) y también solo como un experimento divertido.

Estoy lejos de ser el primero en pensar en esto, http://www.mailvelope.com/ utiliza este

1

Si alguien puede ver los datos de entrada y salida en la conexión de entonces la autenticación no te salvará. En cambio, haría lo siguiente por cosas súper secretas.

Las contraseñas están precedidas por el lado del cliente antes de enviarse al servidor. (El servidor almacena otro valor hash y salado de ese hash enviado desde el navegador).

Así que un ataque de intermediario podría permitirles enviar el mismo valor de hash para iniciar sesión como ellos, pero no se conocería la contraseña de los usuarios. Esto les impediría probar otros servicios con las mismas credenciales para iniciar sesión en otro lugar.

Los datos de los usuarios también están encriptados en el lado del navegador.

Ah, entonces un ataque de intermediario obtendría los datos encriptados, pero no sería capaz de descifrarlos sin la contraseña real utilizada para iniciar sesión. (contraseña de los usuarios almacenada en el DOM en el navegador cuando iniciaron sesión). Entonces el usuario real vería los contenidos descifrados pero el intermediario no podría. Esto también significa que cualquier NSA u otra agencia no podrá solicitarle a usted/compañía/proveedor de servicios de hosting que descifren estos datos ya que sería imposible que ellos también lo hagan.

Algunos pequeños ejemplos de ambos métodos son en mi blog http://glynrob.com/javascript/client-side-hashing-and-encryption/

6

En realidad no estoy de acuerdo que hash lado del cliente es 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 encriptada) es que matemáticamente es imposible obtener la contraseña original de un hash (aunque es teóricamente posible para obtener una entrada hash colisionante, cuya dificultad depende de la seguridad del algoritmo hashing). El posible vector de ataque aquí es que si un atacante potencial de alguna manera comprometía su base de datos de almacenamiento de contraseñas, aún 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 este escenario de violación de seguridad, el atacante no necesita saber la contraseña real - simplemente envían el hash que tienen y listo, tienen acceso a un cuenta particular de usuarios, y por extensión, su sistema completo. Esto en primer lugar derrota por completo el punto de almacenamiento de una contraseña hash.

La manera más segura de hacerlo es enviar al cliente una clave pública de una sola vez para que cifre la contraseña, luego la descifra y vuelve a codificarla en el servidor.

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

+1

Totalmente de acuerdo con esto. Para un enfoque de trabajo del lado del cliente, uno también debería enviar la sal al cliente, ¡lo que invalidaría todo el propósito de la salazón! –

+0

@JamesWright: El objetivo es enviar sal al azar para cada uso, lo que evita la reutilización ilegal de los mensajes de inicio de sesión. (Una forma de ataques de repetición). Enviar la misma sal siempre es inútil. – MSalters

37

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

Use SSL (O realmente TLS, que comúnmente se llama SSL), no es realmente caro (Mida el tiempo que está utilizando para encontrar formas de multiplicarlo con salario mínimo, comprar un certificado gana casi siempre).

El porqué de esto es simple. TLS resuelve un problema (cuando se usa con certificados comprados, no autofirmados) 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 de certificación, en la que confía su navegador, certifica que el sitio web en [url] tiene esta clave pública, con la clave privada correspondiente, que (clave privada) solo el servidor conoce, mira Firmé mi firma en todo el documento, si alguien lo alteró puede ver ".

Sin TLS, cualquier encriptado no tiene sentido, porque si me siento a tu lado en una cafetería, puedo hacer que tu laptop/teléfono inteligente piense que soy el servidor y MiTM (Hombre en el Medio). Con TLS, su computadora portátil/teléfono inteligente gritará "CONEXIÓN INESTIMABLE", porque no tengo un certificado firmado por la autoridad de certificación que coincida con su sitio. (Cifrado vs. Autenticación).

responsabilidad: los usuarios tienden a hacer clic a través de estas advertencias: "Lo que no es de confianza conexión sólo quiero mis fotos de gatitos Añadir ExcepciónHaga clicConfirmarHaga clic YAY gatitos?!?!"

Sin embargo, si usted realmente no quiere comprar un certificado, siendo NO aplicar lado del cliente JavaScript hash (y el uso de la biblioteca de Standford (SJCL) para que, NUNCA IMPLEMENTAR CRYPTO MISMO).

¿Por qué? Contraseña reutilización! puedo robar su cookie de sesión (que me permite fingir a su servidor que yo soy tú) sin HTTPS fácilmente (ver Firesheep). sin embargo, si se agrega un javascript a su página de inicio de sesión, que, antes de enviar, hashes su contraseña (use SHA256, o mejor aún, use SHA256, envíele una clave pública que haya generado y luego cifre hash la contraseña con eso, no puede usar sal con esto), y luego envía el pase hash/encriptado palabra al servidor. REHASH el hash en el servidor con una sal y compararlo con lo que se almacena en su base de datos (almacenar la contraseña de esta manera:

(SHA256(SHA256(password)+salt)) 

(guardar la sal como texto sin formato en la base de datos también)). Y enviar la contraseña de la siguiente manera:

RSA_With_Public_Key(SHA256(password)) 

y comprobar su contraseña así:

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

Porque, SI alguien está oliendo su cliente, que será capaz de iniciar una sesión a su cliente (sesión secuestro) pero van a NUNCA ver la contraseña en texto plano (a menos que alteran su Javascript, sin embargo, un hacker starbucks probablemente no sabe howto/estar interesado en esto.) Así que van a tener 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 usuario o se encontrará en su perfil/configuración en su aplicación web).

+0

Esta es la respuesta correcta. –

0

Considere esto: -

cliente envía una solicitud al servidor "tengo una contraseña para validar".

Server envía un cliente de una sola vez cadena aleatoria. R $

cliente incorpora la contraseña del usuario en esta cadena (en base a cualquier (variable) las reglas que desea aplicar).

cliente envía la cadena al servidor y si bien la contraseña, los registros del servidor de usuario en.

servidor debe recibir otra solicitud de inicio de sesión utilizando R $, el usuario se registra y se congelará la cuenta pendiente de investigación.

Obviamente se tomaron todas las demás precauciones de seguridad (normales).

Cuestiones relacionadas