¿Cuál es la mejor manera de cifrar datos confidenciales almacenados en una base de datos?

Esta es una pregunta que respondo en casi todas las reuniones a las que asisto.

El mayor desafío del cifrado es la gestión de claves. En otras palabras, el cifrado es solo un subproducto de una buena gestión de claves.

La mejor manera de hacer esto es usar un Administrador de claves (Gemalto KeySecure, Vormetric Key Manager son pocos para nombrar) O usar un HSM (Módulo de seguridad de hardware).

Key Manager generará y almacenará la clave dentro de sí mismo. Y en muchos casos también realizará cifrado / descifrado en su memoria segura.

Una vez que elija un administrador de claves, puede decidir cifrar los datos en cualquier nivel

  1. nivel de aplicación: use API para cifrar los datos almacenados antes de que se almacenen en la base de datos.
  2. Nivel de base de datos: use TDE (si está disponible) o use cifrado de nivel de columna (si está disponible).
  3. Carpeta de archivos: si no se pueden realizar más de dos, cifre la base de datos a nivel de carpeta. Esta opción no es encriptar los datos en la base de datos sino encriptar la carpeta de la base de datos.

En todos los casos anteriores, ni la aplicación ni la base de datos tienen acceso completo a las claves. En caso de que alguien copie todo el servidor de la base de datos, nunca podrá recuperar los datos, ya que la clave con la que está cifrada se encuentra en el Administrador de claves.

Luché con la misma pregunta. Esto es a lo que llegué, lo que implementamos y con lo que estamos contentos.

Ciframos y desciframos todo en la aplicación, Java.

Razones:

  • Usamos la base de datos como servicio. Si utilizamos el cifrado integrado en la base de datos, la empresa que proporciona la base de datos puede potencialmente descifrar los datos. Si nos ciframos, es un vector de ataque menos.
  • Separación de inquietudes que nos gustan. El DB lee y escribe datos. El módulo de cifrado hace cifrado. Imho cómo debería ser el código. Mejor legibilidad, facilidad de mantenimiento y más fácil de probar.
  • Es probable que almacene datos en más lugares que la base de datos principal. Por ejemplo, en la base de datos de memoria, una base de datos de valores clave, registros, etc. Con el cifrado separado, la adición de almacenamiento de datos se vuelve más fácil. Y solo un sistema de encriptación para comprender y mantenerse seguro.

Una cosa que hicimos y que estoy muy contento son los prefijos de versión de cifrado. Por ejemplo, v11_thisisencrypteddata. Es decir, cada cifrado (algo + clave (s)) tiene su propio prefijo de versión.

Esto nos permite

  • Usar diferentes cifrados para diferentes conjuntos de datos. Incluso varias claves dentro del mismo conjunto de datos.
  • Actualización de cifrados a medida que cambian los requisitos de seguridad. DES fue considerado seguro hace unos años.
  • Sustitución de llaves que pueden haber tenido fugas o sospecharse que se han roto.
  • Reemplazar gradualmente un tiempo de ejecución de cifrado.

Depende de cuán sensibles sean los datos.

Tener claves de descifrado (ya sea clave simétrica o clave privada) en el mismo host con DB es una mala llamada. En caso de que el host se vea comprometido, toda su base de datos es tan buena como el texto sin formato. Incluso si usa el cifrado de la capa de aplicación, no será difícil realizar ingeniería inversa sobre los algoritmos exactos que se usaron, y su base de datos es tan buena como el texto sin formato nuevamente.

Lo que haría es generar un par de claves fuerte. Mantenga la clave pública con la aplicación, lo que permitirá escrituras cifradas en su base de datos. Luego, dividiría la clave privada usando Shamir’s Secret Sharing [1] en múltiples recursos compartidos, y requeriría un grupo de hosts con seguridad (bastión) para recuperar dicha información, posiblemente a través de un protocolo de chismes [2] de algún tipo.

Rota tus llaves periódicamente.

De esa manera:

  • comprometer su DB produce solo texto cifrado
  • comprometer su aplicación solo produce claves públicas, que no permiten el descifrado
  • comprometer un número suficiente de recursos compartidos de clave privada requerirá violar múltiples hosts de bastión

Notas al pie

[1] El intercambio secreto de Shamir – Wikipedia

[2] Protocolo de chismes – Wikipedia