Para fines de aprendizaje Estoy tratando de crear una aplicación web (Symfony2, PHP) que permita a los usuarios publicar contenido y tener su propia bóveda de contraseñas, todo encriptado. Como quiero que los usuarios puedan compartir contraseñas y contenido cifrado, elegí el cifrado asimétrico para generar un par de claves para cada usuario.
Almacenaré pares de claves de usuarios en la base de datos pero cifraré cada clave privada de usuario con AES-256. Cuando el usuario inicia sesión, debería poder ver sus contraseñas y el contenido al que tiene acceso sin ninguna entrada adicional por parte del usuario.
Esa es la idea general.
Ahora a la solución práctica.
Crear usuario
- generar claves de 4096 bits
- Generar clave de sesión, PBKDF2 (contraseña de usuario)
- Cifrar clave privada con clave de sesión
- Almacenar clave en la base de datos
Cifrar contenido / contraseña
- Generar una clave de almacenamiento aleatoria
- Cifre la contraseña con la clave de almacenamiento utilizando AES-256
- Cifrar la clave de almacenamiento con la clave pública del usuario
- Almacenar clave de almacenamiento encriptada
Inicio de sesión de usuario
- El usuario ingresa la contraseña
- Calcular clave de sesión a partir de contraseña, PBKDF2 (contraseña de usuario)
- Almacenar clave de sesión en sesión
- El usuario solicita contenido cifrado: descifre la clave de almacenamiento con la clave privada del usuario
- Descifrar contenido / contraseña (AES-256) con clave de almacenamiento
Como lo veo, hay dos desventajas principales con este esquema.
-
Guardo la clave de descifrado (la clave de seeion) en la sesión de los usuarios, lo cual no estoy seguro de si está escrito en la carpeta / tmp. Un atacante quizás podría usar algún tipo de secuestro de sesión o si tuviera acceso al servidor, lea la carpeta / tmp.
-
¡La clave privada del usuario no está protegida con frase de contraseña!
¿Solución?
-
¿Cifrado de sesión? ¿O tal vez eso no es necesario ya que Symfony2 maneja los datos de sesión lo suficiente?
-
Genere una cadena aleatoria para usar como frase de contraseña, cifre esta frase de contraseña y almacénela en la base de datos. ¿O usar PBKDF2 (clave de sesión) como frase de contraseña?
El objetivo es poder proteger las contraseñas de los usuarios & contenido lo más posible, aunque el atacante tenga acceso a la base de datos o al servidor.
¿Mi plan suena "bien", o debería simplemente descartarlo? ¿Algún comentario?