Cómo trabajar con el cifrado modular de Parquet
IBM Analytics Engine Serverless da soporte al cifrado modular Parquet, una nueva adición al estándar Parquet que permite cifrar columnas confidenciales al escribir archivos Parquet y descifrar estas columnas al leer los archivos cifrados. Véase cifrado modular Parquet.
Además de garantizar la privacidad, el cifrado Parquet también protege la integridad de los datos almacenados. Se detecta cualquier manipulación indebida con el contenido del archivo y se desencadena una excepción en el lado del lector.
Entra las características principales se incluyen las siguientes:
-
El cifrado y descifrado Parquet se realiza en los trabajadores Spark. Por lo tanto, los datos confidenciales y las claves de cifrado no son visibles en el almacenamiento.
-
Las características de Parquet estándar como, por ejemplo, la codificación, compresión, proyección columnar y el desplazamiento descendente de predicado, siguen funcionando de forma habitual en los archivos con el formato de cifrado modular Parquet.
-
Puede elegir uno de los dos algoritmos de cifrado que están definidos en la especificación de Parquet. Ambos algoritmos dan soporte al cifrado de columnas, sin embargo:
- El algoritmo predeterminado
AES-GCMproporciona una protección completa contra la manipulación indebida con datos y partes de metadatos en los archivos Parquet. - EL algoritmo alternativo
AES-GCM-CTRda soporte a la protección de integridad parcial de los archivos Parquet. Solo las partes de metadatos están protegidas contra la manipulación indebida, no las partes de datos. Una ventaja de este algoritmo es que tiene una sobrecarga de rendimiento inferior en comparación con el algoritmoAES-GCM.
- El algoritmo predeterminado
-
Puede elegir qué columnas cifrar. Otras columnas no se cifrarán, lo que reduce la sobrecarga de rendimiento.
-
Diferentes columnas se pueden cifrar con claves distintas.
-
De forma predeterminada, el módulo de metadatos Parquet principal (el pie de página del archivo) se cifra para ocultar el esquema de archivo y la lista de columnas sensibles. Sin embargo, puede elegir no cifrar los pies de página de archivo para poder habilitar los lectores heredados (como otras distribuciones de Spark que todavía no dan soporte al cifrado Parquet) para leer las columnas sin cifrar en los archivos cifrados.
-
Las claves de cifrado se pueden gestionar de una de las dos maneras siguientes:
- Directamente con la aplicación. Consulte Gestión de claves por aplicación.
- A través de IBM® Key Protect for IBM Cloud®, un sistema de gestión de claves centralizado (KMS) para generar, gestionar y destruir las claves de cifrado utilizadas por IBM Analytics Engine. Consulte Gestión de claves por Key Protect{: {: external}}.
IBM® Key Protect for IBM Cloud® le ayuda a gestionar las claves cifradas alineándolas con los roles de la gestión de identidades y accesos (IAM) de IBM Cloud.
Nota: solo las claves de cifrado maestras (MEK) deben gestionarse (ya sea por aplicación o por Key Protect). Las claves de cifrado de datos (DEK) son manejadas automáticamente por Spark/Parquet. Para obtener detalles sobre cómo manejar claves dentro del cifrado Parquet, consulte Valores internos del manejo de claves de cifrado.
Para cada columna sensible, debe especificar qué clave maestra utilizar para el cifrado. Además, se debe especificar una clave maestra para el pie de página de cada archivo cifrado (marco de datos), porque los pies de página contienen metadatos, como el esquema y la lista de columnas sensibles, que también puede ser sensible. De forma predeterminada, la clave del pie de página se utilizará para el cifrado de pie de página. Sin embargo, si elige una modalidad de pie de página de texto sin formato, el pie de página no se cifrará, y la clave solo se utilizará para la verificación de la integridad del pie de página.
Los parámetros de cifrado se pueden pasar a través de la configuración estándar de Hadoop de Spark, por ejemplo, estableciendo los valores de configuración en la configuración de Hadoop del SparkContext de la aplicación:
sc.hadoopConfiguration.set("<parameter name>" , "<parameter value>")De forma alternativa, puede pasar valores de parámetro a través de las opciones de grabación.
<data frame name>.write .option("<parameter name>" , "<parameter value>") .parquet("<write path>")
Parámetros obligatorios para la ejecución con cifrado Parquet
Se necesitan los parámetros siguientes para escribir datos cifrados:
-
Lista de columnas para cifrar, con las claves de cifrado maestro:
parameter name: "parquet.encryption.column.keys" parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.." -
Clave de pie de página:
parameter name: "parquet.encryption.footer.key" parameter value: "<master key ID>"Por ejemplo:
dataFrame.write .option("parquet.encryption.footer.key" , "k1") .option("parquet.encryption.column.keys" , "k2:SSN,Address;k3:CreditCard") .parquet("<path to encrypted files>")Importante: si no se establece el parámetro
"parquet.encryption.column.keys"ni el parámetro"parquet.encryption.footer.key", el archivo no se cifrará. Si sólo se establece uno de estos parámetros, se lanza una excepción, ya que estos parámetros son obligatorios para los archivos cifrados. -
La clase que implementa
EncryptionPropertiesFactory:parameter name: "parquet.crypto.factory.class" parameter value: "com.ibm.parquet.key.management.IBMKeyToolsFactory"Importante: Si
"parquet.crypto.factory.class"no está establecido, el archivo no se cifrará mediante una fábrica criptográfica.
Parámetros opcionales
Los parámetros opcionales siguientes se pueden utilizar al escribir datos cifrados:
-
El algoritmo de cifrado
AES-GCM-CTRDe forma predeterminada, el cifrado Parquet utiliza el algoritmo
AES-GCMque proporciona una protección total contra la manipulación indebida con datos y metadatos en los archivos Parquet. Sin embargo, puesto que Spark 2.3.0 se ejecuta en Java 8, que no admite la aceleración AES en hardware de CPU (esto solo se ha añadido en Java 9), la sobrecarga de la verificación de la integridad de datos puede afectar al rendimiento de la carga de trabajo en determinadas situaciones.Para compensar esto, puede desactivar el soporte de verificación de la integridad de datos y escribir los archivos cifrados con el algoritmo alternativo
AES-GCM-CTR, que verifica la integridad solo de las partes de metadatos y no de las partes de datos y tiene una sobrecarga de rendimiento inferior en comparación con el algoritmoAES-GCM.parameter name: "parquet.encryption.algorithm" parameter value: "AES_GCM_CTR_V1" -
Modalidad de pie de página de texto sin formato para lectores de legado
De forma predeterminada, el módulo de metadatos Parquet principal (el pie de página del archivo) se cifra para ocultar el esquema de archivo y la lista de columnas sensibles. Sin embargo, puede decidir no cifrar los pies de página de archivo con el fin de habilitar otros lectores Spark y Parquet (que todavía no dan soporte al cifrado Parquet) para leer las columnas sin cifrar en los archivos cifrados. Para desactivar el cifrado de pie de página, establezca el parámetro siguiente:
parameter name: "parquet.encryption.plaintext.footer" parameter value: "true"Importante: el parámetro
"parquet.encryption.footer.key"también debe especificarse en la modalidad de pie de página de texto sin formato. Aunque el pie de página no está cifrado, la clave se utiliza para firmar el contenido del pie de página, lo que significa que los nuevos lectores pueden verificar su integridad. Los lectores de herencia no se ven afectados por la adición de la firma de pie de página.
Ejemplos de uso
Los fragmentos de código de ejemplo siguientes para Python y Scala muestran cómo crear marcos de datos, escritos en archivos Parquet cifrados, y cómo leer archivos Parquet cifrados.
-
Python: Escritura de datos cifrados
from pyspark.sql import RowsquaresDF = spark.createDataFrame( sc.parallelize(range(1, 6)) .map(lambda i: Row(int_column=i, square_int_column=i ** 2))) sc._jsc.hadoopConfiguration().set("parquet.crypto.factory.class", "com.ibm.parquet.key.management.IBMKeyToolsFactory") sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") encryptedParquetPath = "squares.parquet.encrypted"squaresDF.write\ .option("parquet.encryption.column.keys", "key1:square_int_column")\ .option("parquet.encryption.footer.key", "key2")\ .parquet(encryptedParquetPath) -
Python: Lectura de datos cifrados
sc._jsc.hadoopConfiguration().set("parquet.crypto.factory.class", "com.ibm.parquet.key.management.IBMKeyToolsFactory") sc._jsc.hadoopConfiguration().set("parquet.encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") encryptedParquetPath = "squares.parquet.encrypted" parquetFile = spark.read.parquet(encryptedParquetPath) parquetFile.show() -
Scala: Escritura de datos cifrados
case class SquareItem(int_column: Int, square_int_column: Double) val dataRange = (1 to 6).toList val squares = sc.parallelize(dataRange.map(i => new SquareItem(i, scala.math.pow(i,2)))) sc.hadoopConfiguration.set("parquet.crypto.factory.class","com.ibm.parquet.key.management.IBMKeyToolsFactory") sc.hadoopConfiguration.set("parquet.encryption.key.list","key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") val encryptedParquetPath = "squares.parquet.encrypted" squares.toDS().write .option("parquet.encryption.column.keys", "key1:square_int_column") .option("parquet.encryption.footer.key", "key2") .parquet(encryptedParquetPath) -
Scala: Lectura de datos cifrados
sc.hadoopConfiguration.set("parquet.crypto.factory.class","com.ibm.parquet.key.management.IBMKeyToolsFactory") sc.hadoopConfiguration.set("parquet.encryption.key.list","key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") val encryptedParquetPath = "squares.parquet.encrypted" val parquetFile = spark.read.parquet(encryptedParquetPath) parquetFile.show()
Valores internos del manejo de claves de cifrado
Al escribir un archivo Parquet, se genera una clave de cifrado de datos (DEK) aleatoria para cada columna cifrada y para el pie de página. Estas claves se utilizan para cifrar los datos y los módulos de metadatos en el archivo Parquet.
Después, la clave de cifrado de datos se cifra con una clave de cifrado por clave (KEK), generada también dentro de Spark/Parquet para cada clave maestra. La clave de cifrado por clave se cifra con una clave de cifrado maestra (MEK), ya sea localmente si las claves maestras son gestionadas por la aplicación, o en un servicio KeyProtect si las claves maestras son gestionadas por IBM® Key Protect for IBM Cloud®.
Las claves de cifrado de datos cifradas y las claves de cifrado por clave se almacenan en los metadatos del archivo Parquet, junto con la identidad de la clave maestra. Cada clave de cifrado por clave tiene una identidad única (generada localmente como un valor aleatorio seguro de 16-bytes), que también se almacena en los metadatos de archivo. Las claves de cifrado de claves se almacenan en la memoria caché por señal de acceso, por lo que no es necesario interactuar con el servicio KeyProtect para cada archivo o columna cifrados si utilizan la misma clave de cifrado maestra.
Cuando se leer un archivo Parquet, el identificador de la clave de cifrado maestra (MEK) y la clave de cifrado por clave (KEK) cifrada con su identificador, y la clave de cifrado de datos (DEK) cifrada se extraen de los metadatos de archivo.
La clave de cifrado por clave se descifra con la clave de cifrado maestra, ya sea localmente, si las claves maestras son gestionadas por la aplicación, o en un servicio KeyProtect, si las claves maestras son gestionadas por IBM® Key Protect for IBM Cloud®. Las claves de cifrado de claves se almacenan en la memoria caché por señal de acceso, por lo que no es necesario interactuar con el servicio KeyProtect para cada archivo o columna descifrados si utilizan la misma clave de cifrado maestra. A continuación, la clave de cifrado de datos (DEK) se descifra localmente mediante la clave de cifrado por clave (KEK).
Rotación de teclas (característica opcional)
La práctica de cifrado de sobre tiene una opción avanzada para rotar (cambiar) las claves maestras para minimizar el riesgo de filtración de datos confidenciales debido a MEK comprometidas. Las DEK no se pueden cambiar, porque implica volver a cifrar los archivos de Parquet completamente de nuevo. Las nuevas MEK (y las KEK regeneradas de forma transparente) se utilizan para volver a cifrar las DEK.
Para habilitar la rotación de claves en los archivos de Parquet, debe establecer el parámetro "parquet.encryption.key.material.store.internally" en "false" en la configuración de Hadoop al grabar
los archivos de parquet.
Con este conjunto de parámetros, Parquet almacena las claves (encapsuladas con MEK) en archivos pequeños independientes, en lugar de dentro de los archivos de Parquet. Cuando se realiza la rotación de claves, solo se sustituyen los archivos pequeños de material de claves. No es necesario modificar los archivos de Parquet (que suelen ser inmutables). La mayoría de los sistemas KMS admiten la rotación de claves sustituyendo el contenido de las claves maestras almacenadas y manteniendo el ID de MEK intacto (pero actualizando la versión de clave). Después de que un usuario o administrador haya realizado la rotación de clave maestra dentro de la instancia de KMS mediante la API específica de KMS, se puede activar (puede hacerlo, por ejemplo, el mismo administrador) el mecanismo de rotación de claves de Parquet llamando a:
public static void KeyToolkit.rotateMasterKeys(String folderPath, Configuration hadoopConfig)
Cuando se realiza la rotación de claves, todas las KEK de todos los archivos de material de claves de folderPath se desencapsulan con la versión antigua de MEK para habilitar el descifrado de la DEK. Se genera una nueva KEK para
cada ID de clave maestra, y se envuelve con la nueva versión de MEK. La creación de una nueva KEK, en lugar de volver a usar la antigua, no solo significa que mejora la seguridad, sino también que aumenta el rendimiento de las operaciones
de lectura de datos posteriores. Esto se debe a que un único proceso de rotación de claves, ejecutado por el administrador, opera a través de varios archivos creados por diferentes procesos, lo que implica muchas KEK diferentes para el mismo
ID de MEK. El proceso de rotación de claves sustituye a las KEK antiguas con una nueva KEK, lo que permite a los lectores ejecutar una única interacción de desencapsulamiento con KMS para cada clave maestra.
Para ver ejemplos de cómo utilizar la rotación de claves:
- Para la gestión de claves por aplicación, consulte Rotación de claves en la gestión de claves por aplicación.
- Para la gestión de claves mediante Key Protect, consulte Gestión de claves de rotación de claves mediante Key Protect.
Más información
Consulte el siguiente cuaderno de ejemplo para aprender a utilizar el cifrado de Parquet: