Alternativa a SSL – Cifrado “Manual”?

Me gustaría encriptar los datos que viajan de ida y vuelta entre el servidor y el cliente en mi aplicación web. Usaría SSL pero eso requiere un certificado junto con una dirección IP dedicada. No tengo problemas para obtener un certificado, pero la IP dedicada requiere que actualice a un plan de alojamiento de negocios que es de $ 20 al mes en mi host web. No tengo planes de hacerlo porque me estoy quedando con mi plan de alojamiento compartido de $ 20 anuales.

Entonces, me gustaría implementar una alternativa a SSL. Sin embargo, hace más que SSL. Además de encriptar los datos enviados de ida y vuelta, también cifra las filas en la base de datos. Estaba pensando en hacer algo como esto:

Código de JavaScript:

var transfer_key = 'whatever'; function encrypt(data, key) {...} function decrypt(data, key) {...} function send_data_to_server(url, data) { $.post(url, {'data' : encrypt(data, transfer_key) }, function(response) { var decrypted_response = JSON.parse(decrypt(response)); }); } 

Código PHP:

 $data = $_POST['data']; $transfer_key = 'whatever'; $storage_key = 'whatever2'; function encrypt($data, $key) {...} function decrypt($data, $key) {...} databaseQuery('INSERT INTO table VALUES (?)', encrypt($data, $storage_key)); $decrypted_data = decrypt($data, $transfer_key); $response = processData($decrypted_data); echo encrypt($transfer_key, $response); 

Como puede ver, los datos que el cliente envía al servidor están encriptados, y viceversa. Y los datos en la base de datos también están encriptados. Ahora, por supuesto, nunca implementaría las llaves así. Probablemente tendré una segunda o tercera clave generada aleatoriamente para cada usuario. Entonces transfer_key podría ser igual a una constant_key concatenada con una clave aleatoria, y lo mismo vale para storage_key.

¿Esta sería una buena alternativa a SSL? ¿Cómo puedo implementar este tipo de cifrado de tal manera que sea más difícil de vencer? ¿Hay alguna debilidad particular en este enfoque?

Probablemente encuentre una biblioteca JS que se encargue del cifrado y use la extensión mcrypt de PHP para el servidor. Estaba pensando en Blowfish, tal vez AES256, pero no estoy seguro de cuál me da la mejor relación entre la potencia de cifrado y el consumo de memoria.

¿Consejo?

UH oh. Buena suerte con eso. ¿Has echado un vistazo a la especificación TLS ? ¿Crees que puedes encontrar algo adecuado que será probado por millones de personas?

No, en realidad, TLS ha sido probado y mejorado a lo largo de los años por tanta gente, criptógrafos que no hacen más que romper esos protocolos, sería una tarea difícil encontrar algo adecuado.

SSL ha sido desarrollado por expertos en el campo y seguramente también pensaron al principio que su protocolo era absolutamente irrompible. Pero luego estaba la versión 2, luego 3, luego TLS v.1, v1.1 y ahora 1.2.

Si no tiene experiencia previa en el diseño de protocolos seguros, debe apegarse a la stream principal y usar TLS / SSL.

La seguridad es uno de los pocos campos en los que tiene sentido y es realmente genial ir con la stream principal, por lo que yo diría que el dinero adicional sería bien gastado.

Editar:

Tal vez fui un poco duro, y me faltó una explicación de por qué su enfoque no puede competir con un protocolo algo complejo como TLS, así que analicémoslo:

1) ¿Cómo harías el intercambio de claves? Para que AES funcione en ambos extremos, debe realizar un intercambio de claves , para el cifrado simétrico, ambas partes deben poseer la misma clave. Como dijiste, te gustaría generarlo aleatoriamente en el cliente, hasta ahora todo bien. Primer problema: necesitas generar un número aleatorio seguro ; de lo contrario, por ejemplo, usando el generador de números aleatorios Javascript incorporado, los atacantes podrían predecir tus números aleatorios después de un tiempo.

2) Digamos que lo dominaste. Entonces surge el siguiente problema: ¿cómo enviarías esta clave al servidor de manera segura, es decir, realizarías el intercambio de claves? Allí necesitará alguna forma de autenticación del lado del servidor; de lo contrario, cualquiera podría imponer su servidor y hacer esto:

  • engañar a las personas para que envíen sus llaves a su servidor deshonesto primero
  • luego reenvía la clave a tu servidor
  • su servidor enviará diligentemente los datos encriptados con la clave establecida
  • los atacantes interceptarían esa información y leerían sus secretos felizmente descifrando con la clave que robaron

3) Por lo tanto, necesita autenticación de servidor, al menos, si no también autenticación de cliente. Esto implicará que necesita alguna forma de criptografía asimétrica / de clave pública para encriptar / envolver la clave con la clave pública del servidor para que solo el servidor pueda descifrarla.

4) Una vez que dominas eso, sigues siendo susceptible a formas de ataque más involucradas como ataques de repetición , ataques de hombre en el medio , reflections , …

5) Quizás también quieras Perfect Forward Secrecy para que una vez que una clave se vea comprometida, el atacante no sea capaz de descifrar ningún dato pasado. Necesitarás Diffie-Hellman (preferiblemente en su forma de criptografía de curva elíptica ) para lograr esto.

6) Por último, pero no menos importante, un mecanismo de sesión probablemente también sería bueno para que pueda retomar las sesiones anteriores con las claves simétricas ya establecidas, de modo que pueda reducir la carga en el servidor al no tener que volver a establecerlo usando el Algoritmos de clave pública que requieren un uso intensivo de recursos.

-> Agregue un par de características más, tales como negociar de forma segura un conjunto de algoritmos que tanto el cliente como el servidor reconocen para admitir y habrá vuelto a implementar el protocolo TLS.

Lo siento si esto suena un poco sarcástico, pero sé que parece tentador rodar sus propios esquemas de cifrado (también es divertido), pero al final debe quedarse con TLS: es (relativamente) fácil de usar, se ejecuta en el transporte capa (para que pueda codificar sus aplicaciones como si no hubiera ningún cifrado) y, lo mejor de todo, es seguro.

EDITAR: Bueno, recientemente se han producido algunos ataques, pero casi todos los ataques explotaron el “factor humano” en estos protocolos al atacar los certificados de clave pública que respaldan el protocolo (Comodo, DigiNotar, etc. son ejemplos prominentes) o características más arcanas del protocolo como la negociación de algoritmos, etc., pero BEAST ha sido la primera vez que TLS ha sido atacado con éxito en el nivel de criptografía, lo que es interesante y atemorizante al mismo tiempo, porque los fundamentos de ese ataque se conocen desde hace algunos años .

Sin embargo, con las correcciones recientes para BEAST en este momento, apostaría a que TLS sigue siendo la mejor opción para la comunicación segura en la web, especialmente cuando se compara con soluciones hechas a mano.

Ryan: Estoy diciendo esto en lo que espero sea la mejor manera posible: el consumo de memoria es el menor de tus problemas.

No hay nada seguro sobre esto. Nada. Nada .

Está muerto desde el primer envío de ese javascript … No me importa cuánto tiempo tienen tus llaves o qué tan aleatoria es la sal.

Lo que tienes no detendrá a alguien sentado en una cafetería con sus paquetes abiertos de captura de laptops de interceptar las llaves y ser capaz de descifrar fácilmente todo lo que pases de un lado a otro. Diablos, solo ver las palabras “encriptar”, “descifrar” y “clave” en la transmisión sería suficiente para despertar el interés de alguien por bucear más por diversión (o ganancia …). No importa ver una conexión abierta, de repente comienza a transferir partes de los paquetes encriptados y otras partes a la vista.

Si lo que tienes vale la pena encriptar, vale la pena los $ 240 adicionales por año para hacerlo bien. Por favor, dé un paso atrás desde la cornisa y simplemente hazlo bien.

Todo el mundo está siendo tan negativo, y aunque comparto el sentimiento de que usted personalmente probablemente no debería estar haciendo esto, permítame hacer algunas observaciones generales:

Para un canal seguro necesita tres cosas:

  • cifrado de línea
  • intercambio de llaves
  • autenticación

Para el cifrado, debe implementar un cifrado. Eso es factible.

El intercambio clave es el punto crucial: ambos pares deben saber que conocen una clave común sin que nadie más pueda conocer la clave común. Existen protocolos para eso, y debería ser posible implementar eso. SSL está haciendo eso, por ejemplo. El hecho de que pueda oler una conexión SSL y no aprender nada muestra que se puede hacer.

La autenticación es necesaria para detener los ataques de hombre en el medio, y esto requiere algún tipo de intercambio de información fuera de banda (como una llamada telefónica o infraestructura de PKI). Si algo de esto realmente funciona de manera práctica es muy discutible, incluso para SSL.

Entonces, básicamente, si puede implementar todos esos componentes a través de HTTP, entonces, en principio, debería ser posible ejecutar una comunicación segura a través de HTTP. Después de todo, SSL está haciendo lo mismo, está ejecutando un canal seguro en un medio inseguro. Básicamente lo que quieres es implementar SSL en JavaScript. Echa un vistazo a aSSL , han intentado algo así.

Mi consejo es seguir con SSL / TLS. Creo que esto hará que su vida sea más fácil y también le dará a su industria de soluciones una credibilidad reconocida.

En lugar de la dirección IP estática, ¿podría usar DynDNS (o un servicio similar) con un certificado autofirmado?