Estoy creando una pequeña herramienta de línea de comandos (principalmente para diversión) que está destinada a almacenar datos (como contraseñas o archivos) encriptados en una base de datos local, con una contraseña suministrada por el usuario, más o menos la misma funcionalidad que KeePass.
Estoy buscando una revisión de lo que estoy haciendo para confirmar que no estoy dejando ningún agujero de seguridad y estoy usando algoritmos conocidos correctamente o si hay demasiada redundancia.
También es importante la resistencia de la fuerza bruta a los datos.
El proceso es el siguiente:
Encriptación:
-
El usuario proporciona una contraseña y datos
-
Dos claves de 32 bytes se derivan de la contraseña del usuario (llámela d_key y s_key), utilizando PBKDF2 con un 16 RNG de sal (diferente del valor para cada clave) y 10000 iteraciones (configurables)
-
Los datos se cifran utilizando el CTR de AES con d_key y la firma se calcula a partir del texto cifrado mediante HMAC sha512 con s_key
-
Las firmas de texto cifrado y hmac se almacenan en la base de datos, junto con el recuento de sales y iteraciones utilizadas.
Descifrado:
-
El usuario ingresa su contraseña e identificación de los datos que desea recuperar
-
d_key y s_key se generan usando las sales almacenadas existentes y el recuento de iteraciones.
-
Los datos se cargan descifrados usando d_key
-
HMAC se vuelve a calcular a partir de los datos encriptados, utilizando s_key y se compara con el almacenado para confirmar que los datos no se modificaron y la clave es válida.
-
Todos los datos buenos, devueltos al usuario.
Ahora mi pregunta principal es que HMAC parece redundante, pero parece ser la única forma de comprobar que la clave es válida; de lo contrario, habría que comparar un hash de los datos de texto sin formato, lo cual sería muy fácil de revertir. fuerza bruta.
Además, ¿realmente necesito dos claves separadas para AES y HMAC? Incluso si se utiliza una sal?
Por último, ¿ayuda PBKDF2 realmente? ¿O sería lo mismo simplemente usar una función hash para derivar la clave? Dado que la clave no se almacena en ningún lugar, también parece redundante, aunque supongo que si la clave no está salada y bruta iterada podría ser más fácil.