¿Debo cifrar datos confidenciales de formularios con JavaScript en el cliente?

3

Esto no es de ninguna manera un reemplazo para HTTPS, así que no asumas que es por eso que estoy haciendo esta pregunta. Estoy explorando, y tengo curiosidad. Estoy buscando algunos comentarios de expertos sobre esto, y no estoy completamente seguro de dónde debo preguntar esto.

Bien, digamos que estoy enviando información realmente confidencial (por ejemplo, información bancaria). Y quiero dar un paso más para protegerlo.

Con JavaScript, cifraría los datos del formulario cuando se envió. Luego lo descifraría en el servidor (back-end).

  • La primera opción sería utilizar el cifrado asimétrico solo. Cifre los datos del formulario en el envío, con la clave pública. Y dado que es público, no puede hacer daño al cliente saberlo. Luego, en el servidor, descifre los datos con la clave privada. Lo que obviamente es privado, y solo el servidor lo sabe.

  • Muchos de los algoritmos asimétricos son muy lentos por lo que he escuchado, y pueden ser bastante limitados en términos de cuánto puede cifrar (RSA por ejemplo). Entonces, ¿qué pasa con el cifrado híbrido? Cifre los datos del formulario con cifrado simétrico (clave aleatoria generada cada vez), luego encripte la clave simétrica con la clave pública asimétrica. Enviar la clave simétrica junto con los datos. Descifre la clave con la clave privada, use la clave para descifrar los datos.

¿Qué piensas? Estoy un poco perdido en cuanto a lo que sería mejor. Y cómo hacer esto.

    
pregunta user10103279 20.09.2018 - 01:03
fuente

3 respuestas

8

El mejor escenario es que estás perdiendo el tiempo. En general, realizar el cifrado del lado del cliente sobre HTTPS en una aplicación web es mucho trabajo, pero no proporciona seguridad adicional.

El propósito de una capa criptográfica adicional sería proteger contra un MITM que de alguna manera ha logrado descifrar el cifrado TLS. Pero un atacante que lo haya hecho podría modificar fácilmente la fuente JS de su criptografía adicional, simplemente desactivándola. Por lo tanto, esto solo sería útil contra un MITM pasivo que ha descifrado el TLS, y realmente no es un modelo de amenaza por el que valga la pena invertir mucha energía para protegerlo.

También tenga en cuenta que las limitaciones en muchos navegadores (Opera Mini, IE9) para generar números aleatorios seguros hacen que la encriptación del lado del cliente sea difícil. Nunca debe confiar en Math.random para nada relacionado con criptografía.

Debes enfocar tu energía donde tenga el máximo impacto. En lugar de implementar su propio criptografía, asegúrese de estar utilizando la buena criptografía que obtenga de forma gratuita con HTTPS correctamente. Si está preocupado por los ataques MITM, sería mucho mejor gastar el análisis de HSTS y la precarga.

    
respondido por el Anders 20.09.2018 - 15:50
fuente
0

Probablemente no, pero ...

La mayoría de la información descrita en @Anders respuesta fue correcta y debe reconocerse como la respuesta correcta.

Si asumimos que está realizando el cifrado específicamente para la sesión cliente-servidor que se está llevando a cabo, no habrá ningún beneficio adicional solo con el uso de HTTPS.

Sin embargo, como explicó que no está buscando una alternativa a HTTPS, asumiré que está explorando uno de los siguientes escenarios:

  1. Estás creando una arquitectura de servidor de múltiples niveles, donde solo quieres que los servidores con permisos elevados puedan leer los datos confidenciales.

  2. Desea poder almacenar los datos en reposo en alguna base de datos, pero solo quiere que algunos de sus servidores puedan leerlos.

  3. En realidad, solo desea el cifrado del lado del cliente, donde el servidor no puede leerlo, pero puede almacenarlo.

Caveat Emptor

Los tres escenarios se basan en el supuesto de que puede confiar en el código del servidor hasta cierto punto. (Esto podría funcionar en organizaciones estructuradas que tienen una gran revisión de código).

Métodos tradicionales

La opción 1 podría implementarse tradicionalmente habilitando CORS y permitiendo que el cliente se comunique con su servidor "elevado". Sin embargo, esto requiere que abras tu servidor "elevado" a internet.

Esto generalmente involucra la tokenización, y es un enfoque utilizado por muchos procesadores de pago.

La opción 2 podría implementarse en el lado del servidor, mediante el cifrado simétrico antes de insertar los datos en la base de datos.

Métodos no tradicionales (por el bien de la educación)

Supongamos que tiene una combinación única de opciones 1 & 2, o desea explorar la opción 1 sin abrir el servidor a la web abierta.

Sí, podría usar un sistema criptográfico híbrido (asimétrico + simétrico) para cifrar de manera efectiva los datos que solo servidores específicos podrían descifrar. La implementación de un sistema de cifrado de este tipo es un desafío y requiere un conocimiento criptográfico expansivo para hacerlo correctamente.

Para la opción 3, puede cifrar / descifrar de manera simétrica del lado del cliente para proteger los datos del usuario. Es probable que esto requiera que una variable se almacene en localStorage (por conveniencia), lo que conlleva riesgos (es más fácil ocultar el código que lo elimina).

Estos enfoques podrían ayudar a dificultar a los empleados de una organización estructurada el robo de datos de usuarios. Pero solo funciona si no se puede modificar el mecanismo de cifrado de datos o no se pueden robar las credenciales.

El cifrado no será una bala de plata en ningún escenario que pueda imaginar. Puede mitigar bastantes vectores de ataque, pero no los resolverá todos. Necesitarías una revisión intensa del código.

    
respondido por el Jesse Daniel Mitchell 20.09.2018 - 20:57
fuente
-4

El sistema que describe es un cifrado de extremo a extremo (E2EE), que cuando se implementa correctamente puede garantizar que ni siquiera el servidor pueda acceder a los contenidos. Sin embargo, para su uso, los únicos sistemas que podrán descifrar la "información confidencial (SI) " serán el cliente y el servidor.

Al enviar el SI , descargará la clave pública RSA del servidor, es probable que RSA-2048 sea suficiente aquí, ya que puede generar nuevos pares de claves manualmente de manera frecuente. RSA con JavaScript puede ser un buen punto de partida, ya que muestra cómo podría cifrar una cadena con la clave pública y ofrece opciones de descifrado como bien dentro del código fuente. El almacenamiento seguro de la clave privada RSA puede resultar difícil. Puede manejar esto utilizando PHP o Python (a través de una puerta de enlace CGI). Luego, asegúrese de que solo el compilador tenga permisos para acceder a la clave privada, esto mitigará el riesgo. Como si el servidor web tuviera permisos de acceso y estuviera comprometido alguna vez, podría acceder a la clave privada.

A continuación, se requiere una clave de cifrado simétrica (SEK) . Estaba mirando Generar cadenas / caracteres aleatorios en JavaScript , que aunque no son perfectos Para este escenario, debe dar un buen bloque de construcción para lo que se requiere.

No he utilizado una implementación de AES JavaScript antes de que proporcione cifrado AES de Javascript . Sentí que 'JSAES es una poderosa implementación de AES en JavaScript' parecía una opción simple. Sin embargo, esto tendrá que ser tu decisión.

Ahora, cuando envía el texto cifrado (AES cifrado en texto plano) al servidor, debe asegurarse de que el cliente sepa que el descifrado fue posible y permitir la validación. AES_Encrypt(plaintext, key) entonces AES_Encrypt("Validated", "$key") . Esto garantiza que el servidor pudo cifrar un mensaje con la (clave simétrica cifrada) y que el cliente pudo descifrar el mensaje esperado . Debo mencionar que AES de 128 bits o 256 bits será suficiente por igual. Obviamente, AES de 256 bits es mejor, pero dado que el RSA-2048 es la debilidad en la cadena, AES de 128 bits con RSA-2048 podría ser más ideal, ya que la sobrecarga se reducirá.

Ahora estás validado. Asegúrese de que la clave de cifrado simétrica solo sea válida durante X minutos, digamos 60 minutos. Antes de una nueva clave de sesión es necesaria. Esto evitará el abuso de la reutilización de claves.

Para resumir:

  • Fetch RSA public key
  • Generar cadena de 32 caracteres aleatoria (clave simétrica)
  • Cifrar (clave simétrica) con la clave pública RSA
    • produciendo texto cifrado
  • Envíe el texto cifrado al servidor para su descifrado y validación
  • Descifra el texto cifrado con la clave privada
  • Cifre el mensaje esperado (conocido) utilizando AES y la clave simétrica
    • AES_Encrypt("Validated", "$key")
  • El cliente descifra y valida la autenticación segura está completa.
respondido por el safesploit 20.09.2018 - 03:11
fuente

Lea otras preguntas en las etiquetas