Deseo proteger algunos datos altamente confidenciales en una base de datos. Esto significaría que los datos deben cifrarse y mantenerse seguros durante 100 años si caen en manos del adversario. También quiero limitar la cantidad de datos que son vulnerables en texto plano a la vez en la memoria RAM. Esto es así que hay menos posibilidades de que los datos de texto sin formato se paguen al disco. Además, la base de datos puede ser bastante grande, por lo que debe ser más eficiente que descifrar toda la base de datos a la vez solo para acceder a ella. Por lo tanto, estoy pensando en cifrar los datos confidenciales en un nivel de fila de base de datos. Esto significaría que un índice único que hace referencia al registro no está encriptado, por lo que aún se puede encontrar / recuperar cada registro, sin embargo, los datos confidenciales en sí están cifrados.
Mi solución sería tener los datos por fila de la base de datos:
index | IV | sensitive encrypted data | MAC
- Se utilizará una clave de base de datos de 256 bits para cifrar los datos confidenciales que se generarán utilizando / dev / random.
- El IV para cada fila será de 256 bits desde / dev / urandom (más rápido que / dev / random).
- El algoritmo de cifrado será Twofish.
- El MAC de cada registro será HMAC-SHA3 del índice, IV y amp; datos sensibles utilizando la clave.
El sistema es de usuario único. El usuario creará una frase de contraseña alfanumérica fuerte (mínimo 19 caracteres).
Se ejecutará una función de derivación de clave basada en contraseña en la frase de contraseña para crear una clave de cifrado derivada que luego se utilizará para cifrar por separado la clave de la base de datos con Twofish. Esto es para que el usuario pueda cambiar su contraseña sin tener que volver a cifrar toda la base de datos; solo puede crear una nueva contraseña y volver a cifrar la clave de la base de datos. Entiendo que esta es la parte más débil del esquema, pero me gustaría hacer que sea muy difícil para un atacante intentar con la fuerza bruta adivinar con contraseña. Creo que la seguridad debe estar en la fuerza de la frase de contraseña, ya que cualquier tipo de token secundario podría verse comprometido al mismo tiempo que el dispositivo que contiene los datos encriptados (creo que el token del dispositivo podría ser confiscado por razones arbitrarias) al pasar por la seguridad del aeropuerto, por lo que sería inútil).
- Para obtener la clave de la frase de contraseña, PBKDF2 se usará con 10,000 iteraciones utilizando HMAC-SHA3 con una salida de 256 bits y una sal de 256 bits obtenida de / dev / urandom.
- Lo que estoy tratando de hacer es equilibrar el número de caracteres de contraseña necesarios para garantizar la seguridad de los datos en lugar de hacerlo razonablemente rápido para los usuarios en un dispositivo móvil que tienen procesadores lentos y memoria limitada. No espero que el usuario espere más de 5 segundos para que se complete el PBKDF.
- Se crea un MAC utilizando HMAC-SHA3-256 (clave de cifrado derivada, clave de base de datos cifrada con sal) y se almacena junto a la clave de base de datos cifrada y sal en el disco. Esto se puede verificar al iniciar sesión para asegurarse de que ingresaron la contraseña correcta.
Cuando se carga el programa, el usuario ingresa la frase de contraseña. Se ejecuta KDF, que genera la clave para descifrar la clave de cifrado de la base de datos. La clave de cifrado real es lo único que se guarda en la RAM mientras el programa se ejecuta y se usa para verificar y descifrar registros de bases de datos individuales cuando sea necesario.
- ¿Cuál es la longitud óptima para el nivel de fila IV? ¿Está bien 256 bits?
- Es la fuerza de contraseña mínima de 19 caracteres y 10,000 iteraciones de PBKDF2 lo suficientemente fuerte como para proteger la base de datos de 256 bits ¿llave? Si no, ¿qué parámetros funcionarían?
- ¿Es PBKDF2 todavía un buen algoritmo para usar aquí? Si no, ¿qué parámetros de Scrypt?
- ¿Algún cambio o recomendación para que el sistema sea seguro?