¿Es seguro este esquema de autenticación?

0

Quiero autenticar a un cliente de una página web y asegurarme de que sea un usuario en particular.

Digamos que ya acordamos un hash en particular ( SHA256 , en realidad, que creo que es lo suficientemente seguro para esto) y que ambos ya intercambiamos un key en un archivo a través de un medio confiable.

Este key es prácticamente un archivo de texto con 2K de letras aleatorias. Lo tengo almacenado en mi servidor, lo tienen almacenado en algún lugar de su computadora.

Estos son los pasos diseñados para autenticar al cliente:

  1. El servidor genera un challenge , una cadena aleatoria de 128 letras.
  2. El servidor envía el challenge al navegador del cliente.
  3. El cliente tiene acceso a un campo de entrada donde carga su archivo key .
  4. El cliente calcula un answer agregando key a sus contenidos challenge y calcula su hash.
  5. El cliente envía solo el answer para este challenge en particular.
  6. El servidor compara el answer recibido con uno generado localmente y si coinciden, puedo asumir que el cliente es la persona que creo que es.

Supuesto final, el intercambio tanto de challenge como de answer a través de la web puede ocurrir a través de un canal inseguro. En realidad, supongamos que sucederá a través de un canal inseguro, es decir, HTTP.

¿Este esquema es seguro?

Si no, ¿cuáles son sus escollos?

En el paso 4, hace una diferencia si calculo el hash como challenge + key en lugar de key + challenge . Supongo que esto tiene que ver con el algoritmo hash que elegí, y creo que SHA256 maneja esas cosas bien, pero no soy un experto.

¿Importa mucho si aumento / disminuyo la longitud de key y challenge ?

    
pregunta almosnow 01.03.2016 - 15:42
fuente

5 respuestas

62

Ninguna criptografía con JavaScript del lado del cliente puede ser segura sin HTTPS. Cualquier atacante de MITM puede enviar JavaScript que puede hacer cualquier cosa con los secretos a los que el navegador tiene acceso, entonces no habrá ningún secreto.

Si no puede usar HTTPS, el usuario debe tener una herramienta para calcular la respuesta fuera del navegador y pegar el resultado en el navegador. Aun así, cualquier dato transmitido después de la autenticación todavía está sujeto a intercepción y modificación, lo que hace que la autenticación sea bastante inútil desde la perspectiva de la protección del usuario.

Por favor lee:

¿Qué pasa con la criptografía en el navegador? - Tony Arcieri o Javascript criptografía considerada dañina - NCC Grupo o los 1,030,000 resultados devueltos por buscar "mal con la criptografía javascript" en Google

Editar:

Por cierto, incluso si usa un programa externo para manejar la autenticación y tal vez incluso el cifrado de datos que pasa por HTTP, es posible que tenga una seguridad reducida en comparación con solo usar HTTPS. El mejor ejemplo es el cifrado SEED en coreano, que expone a los usuarios al bloquearlos y capacitarlos para que confíen en los controles ActiveX e IE. Consulte este artículo del blog ).

    
respondido por el billc.cn 01.03.2016 - 16:07
fuente
19

Si tiene un ataque de estilo MitM, es inútil: un atacante que se encuentra entre su cliente y su servidor puede reenviar el desafío al cliente, esperar a que lo complete y luego enviarlo de vuelta al servidor, mientras envía un mensaje de rechazo al cliente (y, dado que los está pegando en la clave, también pueden robar eso, si el área de "entrada clave" forma parte del formulario de envío, se incluirá en la solicitud POST realizada) del cliente al servidor. Esto depende de la implementación específica, pero es un error bastante común de cometer).

De forma similar, si el código del lado del cliente se puede modificar de alguna manera (puede: está usando HTTP), sería trivial agregar código para enviar la clave a un tercero, para su uso posterior. Esto no sería obvio para el usuario final.

Si su servidor se ve comprometido en algún momento, todos sus archivos clave pierden su valor, no puede saber si el propietario original o el atacante están intentando conectarse.

La autenticación del cliente HTTPS intenta evitar estos problemas. En primer lugar, es difícil para MitM la conexión, ya que está encriptada con una clave de servidor; tendría que comprometer al servidor para poder usar MitM (sin un defecto de implementación). En segundo lugar, el servidor almacena claves públicas para los clientes. Incluso si son robados, todavía puede usarlos para verificar clientes, ya que no puede regenerar las claves privadas del cliente a partir de ellos. Son publicos No importa quién los tenga. Finalmente, está bien probado y se ha encontrado bastante seguro con el tiempo. Este es un punto clave cuando se utiliza cualquier forma de seguridad: es la forma en que los métodos se consideran seguros o no.

Solo use HTTPS, sí, podría ser difícil de implementar, pero está diseñado para esto.

    
respondido por el Matthew 01.03.2016 - 16:14
fuente
18

La inseguridad es insegura. Si el intercambio pasa por algún HTTP no protegido o algo similar, entonces un atacante activo puede simplemente observar el intercambio inicial, dejar que el cliente realice el paso de autenticación y secuestrar la conexión desde ese punto, reemplazando las solicitudes del cliente con las suyas. El Man-in-the-Middle , por definición, actúa de inmediato, no registrando elementos y reutilizándolos más tarde.

En palabras conceptuales, con su método de autenticación, puede asegurarse de que el cliente esperado estuvo involucrado en algún momento, pero esto no se extiende a los datos de la aplicación que recibe. Los datos no están autenticados.

Si desea solucionarlo, debe cubrir cada elemento de datos enviado por el cliente con un método de autenticación que el servidor pueda verificar, por ejemplo. un MAC . Esto complicará su protocolo, y en ese momento será mejor que ceda a lo inevitable y use SSL / TLS, porque eso es realmente lo que necesita.

(Una pregunta abierta es cómo usar un protocolo orientado a la transmisión como SSL / TLS a través de un medio de transporte que no es una transmisión; esto es típico de situaciones en las que solo se puede usar HTTP simple y el proxy HTTP no está dispuesto a admitir El método CONNECT . Lo mejor que se puede ofrecer en este momento es DTLS , donde los datagramas pueden transmitirse conceptualmente como solicitudes HTTP y respuestas. Pero requeriría una disciplina estricta para que el cliente y el servidor siempre sepan de quién es el turno de hablar, y se sentiría definitivamente torpe.)

Aparte de ese problema fundamental con el alcance de la autenticación, algunas observaciones adicionales:

  • Los archivos de clave de usuario, tal como están almacenados en el servidor, son un objetivo jugoso para los atacantes. Una cinta de copia de seguridad perdida o un ataque de inyección de SQL puede permitir que el atacante lea estos archivos, momento en el que puede hacerse pasar por los usuarios a voluntad. Esto se considera malo cuando los "archivos clave" son en realidad contraseñas de usuario; hablamos de "contraseñas de texto simple".

  • Los archivos clave no son necesariamente mucho secretos. Si el usuario produce su propio archivo de clave, entonces un número deprimente de usuarios simplemente usará una imagen que descargaron de Internet. El atacante puede descargar el mismo archivo ...

  • Si el código del cliente está en Javascript, recién obtenido del servidor web, entonces necesita HTTPS, porque de lo contrario, el atacante podría simplemente modificarlo cuando el navegador del usuario lo descargue.

respondido por el Tom Leek 01.03.2016 - 16:11
fuente
8

¿Por qué preguntar si es seguro en primer lugar si solo va a derribar a alguien que le dice cómo hacerlo?

HTTPS no requiere que el cliente haga nada. Estás actuando como si necesitaran instalar algún software especial o algo, pero el navegador maneja todo eso por ti. Si acaba de implementar el lado del servidor HTTPS, toda su operación se vuelve segura y no necesita su sistema de autenticación personalizado (que podría tener agujeros de seguridad en la implementación / código real).

La realidad es que no vas a estar más seguro que usar HTTPS. Cualquier otra solución es más compleja de hacer y probablemente no sea tan segura.

    
respondido por el JamEngulfer 02.03.2016 - 10:51
fuente
4

Lo que estás haciendo es una especie de autenticación de mensajes a medias, pero un poco a la inversa.

Normalmente, con autenticación de mensajes un cliente creará un mensaje y signar el mensaje con una clave . El mensaje y la firma se envían al servidor. El servidor también tiene la clave para que pueda recrear la firma en sí misma y compararla con la enviada por el cliente. Si coinciden, el mensaje debe ser genuino y no puede haber sido manipulado. Esto se puede usar para verificar la identidad pero no ofrece privacidad (cualquiera puede leer el mensaje).

La identidad se prueba porque los ataques MITM no pueden generar / falsificar la firma correcta sin la clave. Puede ser posible que un MITM use un Replay Attack , pero esto se puede evitar usando un criptográfico Nonce en el mensaje.

En relación con su problema, puede hacer que el cliente firme cualquier solicitud hecha al servidor (es decir, generar un MAC y enviarlo al servidor como parte de la solicitud) para probar la identidad. El servidor no necesita enviar ningún tipo de desafío.

    
respondido por el Qwerky 02.03.2016 - 14:53
fuente

Lea otras preguntas en las etiquetas