No estoy seguro de si esta pregunta encaja mejor en StackOverflowSE o CryptoSE pero creo que este es el lugar correcto.
En un portal de la comunidad en línea, quiero guardar los mensajes privados de los usuarios cifrados en una base de datos para que no se pueda filtrar la información si alguien tiene acceso a la base de datos. Pero no tengo idea de cómo administrar las claves.
Cuando se envía un mensaje, se debe guardar cifrado en la base de datos y solo se debe poder descifrar si uno de los participantes solicita el mensaje. Obviamente, la clave no debe guardarse en la base de datos, ya que no tendría ningún sentido.
La forma en que se me ocurrió es guardar el mensaje con un algoritmo de clave simétrica y guardar la clave cifrada con un algoritmo de clave pública para cada participante (cada usuario tiene una clave pública).
Cuando se solicita un mensaje, se descifra utilizando la clave privada del usuario para obtener la clave simétrica. Sin embargo, no tengo idea de cómo crear / guardar una clave privada. No debe estar en la base de datos y debido a que la aplicación es multiplataforma (web, acceso móvil), no puedo guardarla en el dispositivo del usuario y se debe generar sobre la marcha utilizando una constante que proviene del usuario y no está guardado en algún lugar de la base de datos. La única constante que se me ocurre es la contraseña del usuario. Pero en caso de que la contraseña se pierda o se olvide, ya no hay forma de acceder a los mensajes.
Mi pregunta: ¿Hay otra manera de lograr esto? ¿O conoces otra constante que aún es privada?
Editar / Actualizar: Gracias por tus respuestas. Aquí hay una actualización:
¿Qué hay acerca de guardar la clave privada en db encriptada con una cadena aleatoria que se envía al usuario por correo electrónico una vez en el registro? Se aconseja al usuario que no borre ese correo. Si aún lo hace (parece bastante probable), entonces puedo culparla, bueno, no j / k, pero esa sería al menos la forma de recuperar los mensajes.
Aquí hay una subpregunta: a la aplicación solo se puede acceder a través de HTTPS o TCP / IP + SSL API. ¿Se guarda para en- / descifrar el mensaje en el servidor y enviarlo en formato plano sobre SSL? De lo contrario, tendría que buscar implementaciones (como GPG) para todas las plataformas (navegador, móvil, escritorio). Esto requiere almacenar la clave privada en RAM durante el tiempo que el usuario ha iniciado sesión (la contraseña se envía al inicio de sesión / inicio de sesión). Seguro que si alguien obtiene acceso de escritura al servidor (alterar la aplicación) o acceso de lectura al ram (o0) podría olfatear las teclas pero no creo que esto sea probable.
El mensaje debe estar * en * cifrado en el servidor (significa que se envía sin formato), ya que posiblemente el servidor lo deba enviar a los dispositivos móviles. (No importa si eso es seguro o no, quiero asegurarme de que nadie pueda usar un volcado de base de datos, no si Apple o alguien similar puede leerlo mientras se entrega).
Probablemente no necesito nada de esto, ya que lo más probable es que mis usuarios no se envíen mensajes secretos, pero en caso de una fuga, no estarán contentos. Es una comunidad para estudiantes locales y nunca se sabe lo que hacen los estudiantes aburridos de CS;).