Existe la tarea de diseñar un sistema para almacenar datos confidenciales de forma segura (en el futuro debería ser compatible con HIPAA). Es solo un borrador, no se utilizará en la producción en un futuro previsible. Tengo un prototipo inspirado en TrueVault y quiero saber si hay alguna falta de seguridad semántica o violaciones de los conceptos de seguridad en él.
El sistema consta de 4 subsistemas:
Encryptor / Decryptor (Cryptor) es responsable de la generación aleatoria de claves / iv, el cifrado y descifrado de datos binarios con el algoritmo AES-256-GCM (implementación de OpenSSL). Este servidor realiza solo operaciones en la memoria y almacena el resultado dentro de otros 3 subsistemas y se conecta con ellos a través de IPSEC o SSL VPN. Otros tres subsistemas no tienen conexión directa entre sí. El cliente externo utiliza solo la interfaz pública de encriptador / descifrador y no está directamente conectado a otros subsistemas.
Interfaz pública:
- dump (client_binary_data) - > external_uuid
- cargar (external_uuid) - > client_binary_data
DataStore almacena el triplet [data_store_uuid, encrypted_data, auth_tag].
- dump (encrypted_data, auth_tag) - > data_store_uuid
- cargar (data_store_uuid) - > [encrypted_data, auth_tag]
KeyStore almacena el trío [key_store_uuid, key, iv].
- volcado (clave, iv) - > key_store_uuid
- cargar (key_store_uuid) - > [clave, iv]
MapsStore almacena el mapa entre el triplete DataStore, el triplete KeyStore y external_uuid: [external_uuid, data_store_uuid, key_store_uuid].
- volcado (external_uuid, data_store_uuid, key_store_uuid)
- cargar (external_uuid) - > [data_store_uuid, key_store_uuid]
Flujo de trabajo:
- Cryptor.dump (binario)
- generar external_uuid
- generar clave aleatoria
- generar iv al azar
- use external_uuid como AAD para AES-256-GCM
- cifrar client_binary_data - > encrypted_data
- deriva auth_tag
- KeyStore.dump (clave, iv) - > key_store_uuid
- DataStore.dump (encrypted_data, auth_tag) - > data_store_uuid
- MapStore.dump (external_uuid, data_store_uuid, key_store_uuid)
- Regresar external_uuid al cliente
- Cryptor.load (external_uuid)
- MapStore.load (external_uuid) - > [data_store_uuid, key_store_uuid]
- KeyStore.load (key_store_uuid) - > [clave, iv]
- DataStore.load (data_store_uuid) - > [encrypted_data, auth_tag]
- Descifre los datos y devuélvalos al cliente
Preguntas principales con las que ya estoy en duda:
- hay una forma mejor / más común / confiable de cifrar y almacenar datos. Debería ser lo más rápido posible. Se espera que funcionen con un máximo de 50 MB de manchas.
- debería iv almacenarse en el subsistema KeyStore o en el subsistema DataStore. ¿Hay alguna diferencia entre estos dos enfoques? NIST dice aquí (página 16) que iv es parte del mensaje. Creo que el término "mensaje" es el más cercano a la información almacenada dentro del DataStore en lugar del KeyStore.
- ¿es seguro usar external_uuid como AAD en este esquema? O debería agregar otro uuid aleatorio para ese propósito a MapVault
- ¿Debo cifrar las claves en KeyStore por la clave pública del cliente o alguna clave maestra? Parece que este enfoque utilizado en el esquema de Oracle TDE. Creo que el cifrado con la clave pública del cliente hará imposible restaurar los datos, incluso si los tres subsistemas son robados.