He estado trabajando durante un tiempo en un proyecto favorito para mí: una aplicación para tomar notas similar a Evernote con la diferencia de que todo el contenido está cifrado en el lado del cliente. Me gustaría recibir comentarios sobre algunas decisiones arquitectónicas que hice hasta ahora.
Registro de usuario: Cliente
- El usuario proporciona un correo electrónico y una contraseña
- El cliente genera una clave de cifrado de contenido (CEK) aleatoria mediante un generador de números aleatorios criptográficos. Esta clave se utiliza para cifrar todo el contenido del usuario, incluido el contenido de texto y los recursos multimedia, como imágenes, audio, etc. Si esta clave no existiera como capa intermedia, cambiar la contraseña de un usuario implicaría volver a cifrar todo el contenido.
- Derive una clave para cifrar el CEK mediante:
- var input = padToMaxLength (correo electrónico) + contraseña;
- var salt = SHA512 (entrada)
- var contentKeyEncryptionKey = PBKDF2 (input, salt, 10000)
- Cifre el CEK utilizando contentKeyEncryptionKey derivado del paso anterior
- var encryptedContentKey = AES256 (CEK, contentKeyEncryptionKey) (prefijado con HMAC-256 sobre encryptedContentKey )
- Derive un token de autenticación del servidor con
- var input = contentKeyEncryptionKey;
- var salt = SHA512 (padToMaxLength (correo electrónico) + contraseña)
- var authToken = PBKDF2 (input, salt, 10000)
Registro de usuario: Servidor
- El servidor recibe una solicitud que contiene:
- correo electrónico
- encryptedContentKey
- authToken
-
Genera una sal única por usuario de 256 bits utilizando un generador de números aleatorios criptográficos
-
Genera un token de autenticación del lado del servidor usando:
- var serverSideAuthToken = PBKDF2 (authToken, salt, 100000)
-
Almacena correo electrónico, serverSideAuthToken y encryptedContentKey en la base de datos
Autenticación
- El cliente calcula el token de autenticación del servidor como se describe anteriormente y lo pasa junto con el correo electrónico del usuario al servidor
- El servidor calcula PBKDF2 (authToken, saltFromDatabase, 100000). El usuario se autentica si el correo electrónico y el token derivado coinciden.
Nota: Me doy cuenta de que el uso del correo electrónico y la contraseña para el uso de la sal no es lo ideal.