6

El objetivo es diseñar un sistema simple donde los usuarios puedan enviar mensajes cifrados entre ellos (con la ayuda de un servidor).¿Criptografía de clave pública con contraseñas elegidas por el usuario?

En este caso, los clientes no tienen almacenamiento local, por lo que me veo obligado a utilizar contraseñas que los usuarios podrán elegir, recordar y escribir cuando sea necesario. (sé que esto debilita todo el sistema, pero esto es un requisito duro)

Otro requisito es que el servidor no puede almacenar las claves privadas de texto claro o cualquier otro dato que se puede utilizar para descifrar los mensajes (por ejemplo: solamente el usuario puede leer mensajes cifrados, los administradores del servidor no deberían poder).

Mi enfoque sería generar un par de claves asimétrico en el cliente, publicar la clave pública en el servidor junto con una copia encriptada de la clave privada (cifrada con la contraseña del usuario). Los usuarios pueden enviar mensajes cifrados a otros usuarios, utilizando la clave pública publicada del destinatario; cuando un usuario necesita descifrar un mensaje, su clave privada (cifrada) es captada en el cliente desde el servidor, descifrada con la contraseña proporcionada por el usuario y luego utilizada para descifrar mensajes.

¿Tiene esto sentido? ¿Hay algún defecto en el diseño de este sistema? (aparte de la debilidad derivada de los usuarios que eligen contraseñas cortas o malas) ¿Ya se usa este enfoque en escenarios similares?

Gracias :)

+0

Según lo descrito, suena similar a lo que hushmail.com hace. Tienen libros blancos en su sitio que describen la seguridad. –

+0

Gracias, los echaré un vistazo. – Patonza

Respuesta

2

Si entiendo correctamente, desea crear un sistema donde dos usuarios puedan iniciar una comunicación privada a través de un servidor en el que no confían.

Esto no funcionará.

En el escenario que diseñe, el servidor puede generar su propio par de claves y publicar su clave pública en lugar de la de los usuarios. Cuando un usuario encripta un mensaje, intentándolo por su compañero, no puede detectar que el servidor haya sustituido su clave pública.El servidor descifra el mensaje, lo presenta a los administradores del servidor y vuelve a encriptarlo (o algún mensaje nuevo que fabricaron) con la clave pública del socio real y lo reenvía al destino.

Lo que falta aquí es una autoridad de certificación. Este es un tercero de confianza que firma digitalmente un enlace entre una clave pública y un nombre de usuario. Este enlace se llama certificado. De esta forma, cuando el servidor presenta una clave pública a un cliente para usarla para el cifrado, el cliente puede usar la clave pública de CA para verificar el certificado y tener la seguridad de que la clave pública con la que está a punto de encriptar pertenece al destinatario deseado. y no un atacante

Los usuarios tienen que confiar en la CA, que podría ser más aceptable que confiar en los administradores del servidor. Pero también debe haber una forma a prueba de manipulaciones para almacenar el certificado de CA. En la práctica, esto se hace a menudo usando un MAC basado en contraseña (código de autenticación de mensaje). O bien, la CA podría estar firmada digitalmente con la clave privada del usuario (nunca se ha visto esto hecho, pero funcionaría). Pero la parte difícil sería obtener el certificado de CA de una fuente confiable, evitando el servidor no confiable.

En cuanto al cifrado de la clave privada con la contraseña, esto se hace con mucha frecuencia y es tan seguro como la contraseña que usted elija.

Alternativamente, si los usuarios pueden compartir un secreto entre ellos fuera de banda, no es necesario el cifrado de clave pública. El cliente podría cifrar el secreto compartido con una contraseña seleccionada por el usuario y almacenar el texto de cifrado en el servidor.

+0

Sí, parece que no funcionará. Supongo que tendré que encontrar la forma de usar una CA de confianza :) Gracias por los consejos. De todos modos, solo para saber, suponiendo que el servidor no ha sido manipulado, un atacante que solo puede obtener acceso de * lectura * al servidor no podría interceptar nada, ¿o sí? Además, si la confianza se asigna una sola vez con un sistema diferente (por ejemplo, usando un cliente que puede verificar contra una CA confiable) y luego se almacena, encriptada, en el servidor, entonces debería funcionar, ¿no es así? – Patonza

+0

@Patonza - Sí, si la confianza se estableció inicialmente con una CA confiable, el cliente podría almacenar la clave pública del socio en el servidor * autenticándolo * (no * encriptado *) con su propia contraseña. Debido a que los datos almacenados están protegidos con un MAC, el servidor no puede alterarlo. – erickson

+0

Si un ataque solo tenía acceso de lectura en el servidor, no podía modificar los mensajes que lo atraviesan, si eso es lo que quiere decir. Pero el ataque que describo fue donde el servidor estaba corrupto. – erickson

1

Como se ha descrito, el esquema parece razonable que debería permitir a alguien para enviar un mensaje a otra persona que sólo el destinatario puede leer. Hay algunos elementos que vienen a la mente que es probable que haya pensado, pero excluido por razones de brevedad:

  • Al cifrar la clave privada, usar algo como PBKDF2 con sal y un poco número bastante grande que iteraciones.
  • Esto probablemente esté implícito, pero en lugar de encriptar con la clave pública, probablemente tenga sentido generar una clave aleatoria (por ejemplo, 32 bytes de datos aleatorios si se usa, por ejemplo, AES-256). Encripte el mensaje con esa clave, encripte la clave con la clave pública y envíe ambas piezas.
  • Como se describió, no hay identificación del remitente. Permite el envío de mensajes puramente anónimos. Esto podría ser intencionado, pero de lo contrario, sería necesario algún tipo de identificación/autenticación.
  • Algo similar a la entrada anterior, no se describe la autenticación de mensajes. El atacante podría cambiar el mensaje cifrado y el destinatario no podría decir que se modificó. Aunque, si se trata de un mensaje de texto, sería bastante claro que se había modificado, porque sería solo un texto confuso. Sin embargo, hay algunos tipos de datos que podrían no ser tan fáciles de decir si se modificaron.
+0

Gracias, su punto acerca de la identificación del remitente/autenticación de mensaje, aunque no es mi prioridad en este diseño específico, es interesante: probablemente los mensajes podrían firmarse con otro par de claves y los clientes podrían almacenar un directorio cifrado de claves conocidas/confiables en el servidor - Veré esto. Y seguiré su consejo sobre PBKDF2, que parece ser el estándar de la industria para el fortalecimiento de claves. :) – Patonza

+0

@Patonza - Sin autenticación, no puede tener privacidad. Privacidad significa guardar un secreto de "alguien". Si no sabe con quién está hablando, ¿cómo sabe que no es "alguien"? – erickson

+1

P.S. Si bien creo que esta respuesta es incorrecta (implica que el sistema propuesto solo permitirá que el destinatario intente descifrar un mensaje), el consejo en cada viñeta es extremadamente bueno y debe considerarse cuidadosamente si se implementa un sistema real. – erickson

1

Esto suena algo así como lo que hizo Hushmail. Sin embargo, había un gran problema, ya que tenían la clave privada de los usuarios (cifrada), simplemente tenían que presionar hacia abajo un applet java pirateado que transmitiría la contraseña del usuario al servidor (lo cual hicieron).

Una solución mucho mejor es evitar tener esa clave privada en el servidor. Con el requisito de no almacenamiento local, eso está fuera.

¿Por qué no utilizar el cifrado simétrico a través de una contraseña precompartida? Se puede hacer sin almacenamiento en el lado del cliente. Creo que esto es lo que dijo @erickson en su último párrafo.

+0

No estoy suponiendo que el código del cliente deba ser descargado del servidor. Se puede almacenar de solo lectura en el cliente. Encriptación simétrica no es una opción aquí, porque los usuarios tendrían que "cumplir" antes de poder compartir datos. Gracias por el consejo de todos modos :) – Patonza

1

El principal problema es que si el código de descifrado se descarga del servidor, uno (ya sea el administrador del servidor o un hacker que haya llegado al servidor) puede reemplazar este código. El usuario del lado del cliente debe confiar en el servidor, pero no tiene forma de verificar el servidor para confiar en él.

Cuestiones relacionadas