Con la próxima apertura del nuevo ciclo del curso seguimos publicando una serie de artículos sobre cifrado en MySQL.

En el artículo anterior de esta serie () hablamos sobre los almacenes de claves. En este artículo, examinaremos cómo se utiliza la clave maestra (master key) y discutiremos las ventajas y desventajas del cifrado por medio de sobres (envelope encryption).
La idea del cifrado por sobres es que las claves utilizadas para cifrar (las claves de los espacios de tabla) son cifradas con otra clave (la clave maestra, master key). Para cifrar los datos, se utilizan en realidad las claves de los espacios de tabla. Gráficamente, se puede representar así:

La clave maestra (master key) se encuentra en el almacén de claves (keyring), mientras que las claves de los espacios de tabla están en los encabezados de los espacios de tabla cifrados (en la página 0 del espacio de tabla).
En la imagen anterior:
La tabla A está cifrada con la clave 1 (Key 1). La clave 1 es cifrada con la clave maestra (master key) y se almacena en forma cifrada en el encabezado de la tabla A.
La tabla B está cifrada con la clave 2 (Key 2). La clave 2 es cifrada con la clave maestra (master key) y se almacena en forma cifrada en el encabezado de la tabla B.
Y así sucesivamente.
Cuando el servidor necesita descifrar la tabla A, obtiene la clave maestra del almacén, lee la clave 1 cifrada del encabezado de la tabla A y descifra la clave 1. La clave 1 descifrada se almacena en caché en la memoria del servidor y se utiliza para descifrar la tabla A.
InnoDB
En InnoDB, el cifrado y descifrado reales se realizan a nivel de entrada y salida. Es decir, la página se cifra justo antes de ser escrita en el disco y se descifra inmediatamente después de ser leída del disco.
En InnoDB, el cifrado funciona solo a nivel de los espacios de tabla. Y por defecto, todas las tablas se crean en espacios de tabla separados (). En otras palabras, se crea un espacio de tabla que puede contener solo una tabla. Aunque también puedes crear tablas en el espacio de tabla principal (). Pero en cualquier caso, la tabla siempre se encuentra en algún espacio de tablas. Y dado que el cifrado se realiza a nivel de espacio de tablas, está completamente cifrado o no. Es decir, no se puede cifrar solo una parte de las tablas en el espacio de tablas principal.
Si por alguna razón tiene desactivada la opción file-per-table, todas las tablas se crean dentro del espacio de tablas del sistema (system tablespace). En se puede cifrar el espacio de tablas del sistema utilizando la variable innodbsystablespaceencrypt o usando hilos de cifrado (encryption threads), pero sigue siendo una función experimental. En MySQL esto no existe.
Antes de continuar, necesitamos considerar la estructura del identificador de la clave maestra (master key ID). Se compone de UUID, KEYID y el prefijo «INNODBKey». Se ve así: INNODBKey-UUID-KEYID.
UUID es el uuid del servidor con el espacio de tablas cifrado. KEYID es simplemente un valor que aumenta constantemente. Al crear la clave maestra por primera vez, KEYID es igual a 1. Al rotar la clave, cuando se crea una nueva clave maestra, KEYID = 2 y así sucesivamente. Hablaremos más sobre la rotación de claves maestras en los próximos artículos de esta serie.
Ahora que sabemos cómo se ve el identificador de la clave maestra, veamos el encabezado del espacio de tablas cifrado. Cuando se cifra el espacio de tablas, la información sobre el cifrado se agrega al encabezado. Se ve así:

KEY ID es el KEYID del identificador de la clave maestra que ya hemos discutido. UUID es el uuid del servidor, que también se utiliza en el identificador de la clave maestra. TABLESPACE KEY es la clave del espacio de tablas, que consta de 256 bits generados aleatoriamente por el servidor. El vector de inicialización (IV, initialization vector) también consta de 256 bits generados aleatoriamente (aunque debería ser de 128 bits). El IV se utiliza para inicializar el cifrado y descifrado AES (de los 256 bits, solo se utilizan 128). Al final, hay una suma de verificación CRC32 para la TABLESPACE KEY y el IV.
Todo este tiempo he simplificado un poco al decir que en el encabezado hay una clave de espacio de tabla cifrada. En realidad, la clave del espacio de tabla y el vector de inicialización se almacenan y se cifran junto con la clave maestra. Recuerde que, antes de cifrar la clave del espacio de tabla y el vector de inicialización, se calcula el CRC32 para ellos.
¿Para qué sirve el CRC32?
En pocas palabras, para asegurarse de que la clave maestra sea válida. Después de descifrar la clave del espacio de tabla y el vector de inicialización, se calcula una suma de verificación y se compara con el CRC32 almacenado en el encabezado. Si las sumas de verificación coinciden, tenemos la clave maestra y la clave del espacio de tabla correctas. De lo contrario, el espacio de tabla se marca como ausente (de todos modos no podremos descifrarlo).
Puede preguntar: ¿en qué momento se realiza la verificación de las claves? La respuesta es: al iniciar el servidor. El servidor con tablas cifradas / espacios de tabla lee UUID, KEYID del encabezado y genera un identificador de clave maestra. Luego obtiene la clave maestra necesaria del almacén (keyring), descifra la clave del espacio de tabla y verifica la suma de verificación. Una vez más, si la suma de verificación coincide, todo está en orden; de lo contrario, el espacio de tabla se marca como ausente.
Si ha leído el artículo anterior de esta serie (), es posible que recuerde que al utilizar un almacén de claves del servidor, el servidor al iniciarse obtiene solo una lista de identificadores de claves, más precisamente, el key id y user id, ya que este par identifica de manera única la clave. Y ahora digo que el servidor al iniciarse obtiene todas las claves necesarias para verificar la posibilidad de descifrar las claves de los espacios de tabla. Entonces, ¿por qué al inicializar, en el caso del almacén de claves del servidor, solo se cargan el keyid y userid, y no todas las claves? Porque es posible que no necesite todas las claves. Esto está relacionado principalmente con la rotación de la clave maestra. Al rotar la clave maestra, se crea una nueva clave maestra en el almacén, pero las claves antiguas no se eliminan. Así, en el almacén de claves del servidor puede haber muchas claves que no son necesarias para el servidor y, por lo tanto, no se extraen al iniciar el servidor.
Es el momento de hablar un poco sobre las ventajas y desventajas de la cifración utilizando una clave principal. La mayor ventaja es que solo necesitas una clave de cifrado (la clave principal), que se almacenará por separado de tus datos cifrados. Esto hace que el lanzamiento del servidor sea rápido y el almacenamiento sea pequeño, lo que facilita la gestión. Además, la única clave principal es fácil de regenerar.
Sin embargo, la cifración con la clave principal tiene una gran desventaja: una vez que el espacio de tablas está cifrado con tablespace_key, siempre permanece cifrado con la misma clave. La rotación de la clave principal no ayuda aquí. ¿Por qué es esto una desventaja? Sabemos que en MySQL hay errores que pueden provocar un fallo repentino y la creación de un archivo core. Dado que el archivo core contiene un volcado de la memoria del servidor, puede suceder que en el volcado se encuentre la clave descifrada del espacio de tablas. Peor aún, las claves descifradas del espacio de tablas se almacenan en memoria, que puede intercambiarse en el disco. Puedes decir que esto no es una desventaja, ya que se necesitan privilegios de root para acceder a esos archivos y a la partición de intercambio. Sí. Pero se necesita root solo por un tiempo. Tan pronto como alguien obtenga acceso a la clave descifrada del espacio de tablas, él o ella podrá seguir usándola para descifrar datos, incluso sin privilegios de root. Además, el disco puede ser robado, y la partición de intercambio o los archivos core pueden ser leídos usando herramientas de terceros. El objetivo de TDE es hacerlo ilegible, incluso si el disco es robado. Hay una opción para volver a cifrar el espacio de tablas con nuevas claves generadas. Esta función se llama hilos de cifrado (encryption threads) y, en el momento de escribir este artículo, aún es experimental.
Leer más:
Fuente: habr.com
