2012-03-23 19 views
7

Después de ver un video de YouTube en el Diffie-Hellman Key Exchange, quería probar una implementación en JavaScript (ley de Atwood).Encriptación del lado del cliente a través de HTTP con Diffie-Hellman Key Exchange y AES

he esbozado hasta un cifrado en Node.js con las siguientes reglas:

  • Paso 1: El cliente y el servidor están de acuerdo en una clave compartida:

    • cliente de inicio & servidor con una Clave pública principal de 512 bits pK

    • El cliente genera una clave privada primaria de 512 bits kC y envía powMod (3, kC, pK)

    • Server genera un 512bit de primera clave privada Ks y envía powMod (3, KS, PK)

    • cliente & uso del servidor powMod (respuesta, PrivateKey, PK) como la clave compartida

  • Paso 2: Comunicación

    • Antes de que un cliente envía los datos se cifra con la clave compartida utilizando la biblioteca JavaScript Crypto Stanford (256 AES, autenticación HMAC, refuerzo de contraseña PBKDF2 y cifrado CCM autenticado).

    • Una vez que el servidor descifra los datos con la clave compartida, genera una nueva clave privada principal de 512 bits y la envía como una respuesta cifrada SJCL.

    • El interruptor de cliente y servidor para una nueva clave compartida utilizando powMod (3, prevSharedKey, newPrivKey)

ahora tengo un par de preguntas ..

¿Qué tan seguro como lo haría un sistema en comparación con HTTPS u otros algoritmos? ¿Cuáles son los puntos más débiles de tal sistema?

En términos de seguridad/practicidad, ¿sería mejor usar llaves de 1024 bits para una mayor seguridad? ¿Las opciones de HMAC/PBKDF2/CCM son excesivas? ¿Vale la pena modular la clave compartida? ¡Gracias por leer!

Respuesta

7

que he visto este tipo de preguntas before – esto es completamente inseguro for a number of reasons, sobre todo de los cuales es el hecho de que es imposible para un cliente JavaScript para verificar que la clave del servidor es auténtico.

En pocas palabras, sin SSL, usted es vulnerable a los ataques de hombre en el medio. Ninguna implementación de criptografía JavaScript basada en navegador puede superar este hecho.

+0

Hrmm. Suponiendo que pudiera obtener el javascript ejecutándose en la máquina cliente con la confianza de que no se había modificado (posiblemente una tarea imposible), ¿sería menos inseguro? No creo que las modificaciones en los datos (excluyendo la entrega inicial del applet) lo comprometerían. – arby

+6

En términos prácticos, la única forma de obtener JS para el cliente de manera confiable es a través de SSL. Y como su conexión ya está asegurada, ¿de qué sirve hacer su propia criptografía en ese punto? – josh3736

+0

Ataques de renegociación: http://www.openssl.org/news/secadv_20091111.txt, http://lwn.net/Articles/362234/ Ataques de descifrado de cifrado: http://www.openssl.org/news/ secadv_20101202.txt, http://wroot.org/posts/preventing-your-servers-from-downgrade-attacks/ –

15

Su sistema es enormemente inseguro, pero no estoy tratando de disuadirlo ni a usted ni a nadie de jugar con cosas como esta. Deberías continuar. Pero es vital que consideres que todo lo que creas sea un sistema de "juguete" que nunca se debe considerar ni publicitar como "seguro".

Vamos a desglosar la pregunta de seguridad en dos partes.

  1. ¿Qué tan seguro es el intercambio de claves?
  2. ¿Cuán seguro es el cifrado que utiliza una vez que tiene una clave compartida?

Déjame responder (2) primero, ya que será el más simple. Será terriblemente inseguro a menos que sea más inteligente que todas las personas que han trabajado y estudiado TLS a lo largo de los años. TLS antes de la versión 1.2 (que pocos sitios usan) es vulnerable a los Ataques de texto cifrado (CCA) elegidos en principio y al BEAST attack en la práctica, dependiendo de la elección del traje de cifrado. Y SSL 2.0 está más roto.

El punto es que las personas muy inteligentes, trabajando con estos protocolos durante años, cometieron errores. Hay muchas razones para creer que estás trabajando en este tipo de cosas por tu cuenta y cometerás grandes errores. Los algoritmos básicos de encriptación están bien. Ellos no están rotos. Pero los protocolos son

Así que si no ha estudiado y comprendido completamente todos los detalles de SSL, por qué están allí y cómo han salido mal en algunos casos, entonces es casi seguro que cualquier protocolo que diseñe será terrible.

Ahora a la pregunta (2). Hay dos problemas con esto. (a) Diffie-Hellman no está diseñado para proporcionar el tipo de seguridad que probablemente necesite; y (b) no creo que haya implementado DH correctamente.

2.a:

Diffie-Hellman de intercambio de teclas, cuando se hace bien, es seguro para el intercambio de claves, pero no hace nada para la autenticación. Esta es la razón por la cual la pregunta "¿es seguro?" Es a menudo la pregunta equivocada. Es seguro para algunos propósitos, pero masivamente inseguro para otros ya que no está diseñado para esos otros fines.

Como Josh3737 señaló que no hay forma de que el cliente y el servidor sepan que están hablando con la persona adecuada. Si Sam es el servidor y Charlie es el Cliente, no hay nada que impida que Mallory configure su propio servidor que se hace pasar por Sam. Entonces Cathy puede pasar por el intercambio de claves con Mallory, pensando que ella está hablando con Sam. Mallory puede pretender ser Charlie cuando habla con Sam.

Una vez configurado de esta manera, Mallory puede actuar como un hombre en el medio entre Sam y Charlie. Cuando Charlie envía los datos destinados a Sam, Mallory los descifrará usando la clave compartida entre C y M, lo leerá (y posiblemente lo cambiará), y luego volverá a encriptar la clave compartida entre M y S y lo enviará a S

Para resolver el problema de autenticación, necesita algún tipo de infraestructura de clave pública (PKI) y estos son realmente un problema. El sistema de Autoridades de certificación y tal que tenemos con SSL/TLS está plagado de problemas, pero sigue siendo el mejor sistema que existe.

2.b:

Un módulo público de 512 bits, junto con las claves privadas de 512 bits no son lo suficientemente fuertes. Las claves DH deben ser más grandes. No iría con nada menos que 2048 bits. Puede salir con 1024 bits, no le preocupa que alguien pueda descifrar los secretos de hoy dentro de cinco años.

No proporcionó información suficiente sobre cómo se seleccionaron sus números primos. No todos los primos funcionarán. Debe usar una "prima segura" para su módulo, de lo contrario, hay atajos disponibles para que un atacante calcule el logaritmo discreto.

+1

Excelente información. ¡Gracias! – arby

+0

En realidad estaba pensando que DH sobre HTTPS/TLS podría funcionar bastante bien ... Mis preocupaciones son las CA potencialmente corruptas, y que la combinación de DH con un canal autenticado podría ser al menos interesante ... gracias por su consejo sobre el módulo/las longitudes de las claves, aunque mi mayor preocupación sería por el tiempo que le llevaría a un navegador calcular el secreto compartido (por ejemplo, en un teléfono inteligente típico) en JS. – Tracker1

0

Si desea evitar el certificado SSL y el hombre en el problema del medio, puede usar la cadena de bloques bitcoin. (O una cadena de bloques altcoin.)

The Huge Caveat: el cliente tiene que descargar o mantener un archivo completo de la cadena de bloques.

Hay dos pares de claves pública/privada:

CERTpublic CERTprivate

CLIENTpublic CLIENTprivate

NOMBRE DE REGISTRO:

Server -> CERTpublic and name_to_register -> Bitcoin Blockchain 

conexión autenticada:

Client <- CERTpublic <- Bitcoin Blockchain 
Client -> CERTpublic(CLIENTpublic) -> Server or Adversary 
Client <- No_response_or_incorrect <- Adversary 
Client <- CLIENTpublic(CERTprivate(content)) <- Server 
Cuestiones relacionadas