He desarrollado una aplicación web (desarrollada en .NET MVC 4) que tiene múltiples usuarios con credenciales de inicio de sesión personales. La aplicación web contiene una gran cantidad de contenido cargado por los usuarios.
Mi cliente también desea tener una versión sin conexión de la aplicación, para Windows. Esta aplicación debe utilizar la misma información disponible en la web, debe estar disponible fuera de línea y debe estar protegida de manera que el usuario no pueda tomar el contenido de la aplicación y dárselo / venderlo a un competidor (en una manera fácil).
Por lo tanto, en mi aplicación web he implementado una funcionalidad para crear un paquete de aplicaciones que contiene toda la información relevante, que se puede descargar y cifrar con una clave simétrica. Sin embargo, cada usuario debe poder descifrar el paquete con sus credenciales (es decir, contraseñas personales).
Entonces, cuando se crea un usuario, creo un par de claves asimétricas para ese usuario, y la clave privada se almacena en la base de datos como una cadena encriptada donde la clave es la contraseña privada (almacenada como un hash de bcrypt).
Esta lista de eventos significa que hay una gran cantidad de cifrado anidado y me hace sentir incómodo porque no sé si es lo suficientemente seguro, por lo que me gustaría recibir algunos comentarios sobre mi método de elección.
La cadena de funcionalidad;
Al crear un usuario;
- Crear un par de claves asimétricas
- Cifre la clave privada con la contraseña de la credencial del usuario
- hash la contraseña con bcrypt
- Almacene hash + clave privada cifrada para el usuario
Al crear un paquete de aplicación;
- Crear una clave simétrica [lado del servidor]
- Cree un paquete de aplicación (datos sin procesar) y cifrelo con el clave simétrica [lado del servidor]
- Para cada usuario, cifre la clave simétrica con la clave pública de los usuarios y almacene el resultado para que se pueda descargar [lado del servidor]
- Un usuario inicia sesión para descargar el paquete + cifrado simétrico clave + clave privada encriptada [lado del servidor]
- Descifre la clave privada, encriptada y almacenada con la credencial del usuario contraseña [lado del cliente]
- Descifre la clave almacenada, cifrada y simétrica con el ahora descifrado clave privada para el usuario [lado del cliente]
- Descifre el paquete de la aplicación (en la memoria de la computadora del cliente) y muestre el contenido a través de un pequeño servidor integrado [lado del cliente]
¿Es esta una forma bastante segura de resolver mi problema? ¿Puedo hacerlo de otra manera? ¿Hay agujeros de seguridad obvios en esta solución?