Si los datos se almacenan en formato de columnas, puede utilizar el cifrado modular Parquet para cifrar las columnas confidenciales al escribir los archivos Parquet y para descifrar estas columnas al leer los archivos cifrados. El cifrado de datos en el nivel de columna le permite decidir las columnas que se van a cifrar y cómo controlar el acceso a la columna.
Además de garantizar la privacidad, el cifrado modular de Parquet también protege la integridad de los datos almacenados. Se detecta cualquier manipulación del contenido del archivo y se desencadena una excepción del lado del lector.
Entra las características principales se incluyen las siguientes:
El cifrado y descifrado modular de Parquet se realiza en el clúster Spark. Por lo tanto, los datos confidenciales y las claves de cifrado no resultan visibles en el almacenamiento.
Las características de Parquet estándar, como por ejemplo la codificación, la compresión, la proyección columnar y el desplazamiento descendente de predicado, siguen funcionando de la 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 Parquet. Ambos algoritmos dan soporte al cifrado de columnas, sin embargo:
- El algoritmo predeterminado
AES-GCM
proporciona una protección completa contra la manipulación indebida con datos y partes de metadatos en los archivos Parquet. - El algoritmo alternativo
AES-GCM-CTR
da soporte a la protección de la integridad parcial de los archivos Parquet. Solo partes de los metadatos están protegidas contra la manipulación indebida, no partes de los 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 las columnas que se van cifrar. Otras columnas no se cifrarán, reduciendo la sobrecarga de rendimiento.
Se pueden cifrar diferentes columnas con claves distintas.
De forma predeterminada, el módulo de metadatos de Parquet principal (el pie de página del archivo) se cifra para ocultar el esquema del archivo y la lista de columnas confidenciales. Sin embargo, puede optar por no cifrar los pies de página para permitir que lectores antiguos (como por ejemplo otras distribuciones de Spark que todavía no dan soporte al cifrado modular de Parquet) puedan leer las columnas no cifradas 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.
- Con un sistema de gestión de claves (KMS) que genera, almacena y destruye las claves de cifrado que utiliza el servicio Spark. Estas claves nunca salen del servidor KMS y, por lo tanto, son invisibles para otros componentes, incluido el servicio Spark. Consulte Gestión de claves con KMS.
Nota: Solo las claves de cifrado maestras (MEK) deben ser gestionadas por la aplicación o por KMS.
Para cada columna confidencial, debe especificar la clave maestra que se va a utilizar para el cifrado. Asimismo, se debe especificar una clave maestra para el pie de página de cada archivo cifrado (marco de datos). De forma predeterminada, se utilizará la clave del pie de página 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 opciones de escritura:
<data frame name>.write .option("<parameter name>" , "<parameter value>") .parquet("<write path>")
Ejecución con cifrado Parquet modular
El cifrado Parquet modular solo está disponible en los cuadernos de Spark que se ejecutan en una instancia del servicio IBM Analytics Engine. El cifrado Parquet modular no está soportado en los cuadernos que se ejecutan en un entorno de Spark.
Para habilitar el cifrado Parquet modular, establezca las siguientes propiedades de classpath de Spark de modo que apunten a los archivos JAR de Parquet que implementan el cifrado Parquet modular y al archivo JAR de gestión de claves:
Vaya hasta Ambari > Spark > Config -> Personalizar spark2-default.
Añada los dos parámetros siguientes de modo que apunten de forma explícita a la ubicación de los archivos JAR. Asegúrese de que edita las vías de acceso para que utilicen la versión real de los archivos jar del clúster.
spark.driver.extraClassPath=/home/common/lib/parquetEncryption/ibm-parquet-kms-<latestversion>-jar-with-dependencies.jar:/home/common/lib/parquetEncryption/parquet-format-<latestversion>.jar:/home/common/lib/parquetEncryption/parquet-hadoop-<latestversion>.jar spark.executor.extraClassPath=/home/common/lib/parquetEncryption/ibm-parquet-<latestversion>-jar-with-dependencies.jar:/home/common/lib/parquetEncryption/parquet-format-<latestversion>.jar:/home/common/lib/parquetEncryption/parquet-hadoop-<latestversion>.jar
Parámetros obligatorios
Se necesitan los parámetros siguientes para escribir datos cifrados:
Lista de columnas para cifrar, con las claves de cifrado maestro:
parameter name: "encryption.column.keys" parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.."
Clave de pie de página:
parameter name: "encryption.footer.key" parameter value: "<master key ID>"
Por ejemplo:
dataFrame.write .option("encryption.footer.key" , "k1") .option("encryption.column.keys" , "k2:SSN,Address;k3:CreditCard") .parquet("<path to encrypted files>")
Importante:Si no se establece el parámetro
encryption.column.keys
ni el parámetroencryption.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.
Parámetros opcionales
Se pueden utilizar los siguientes parámetros opcionales al escribir datos cifrados:
El algoritmo de cifrado
AES-GCM-CTR
De forma predeterminada, el cifrado modular de Parquet utiliza el algoritmo
AES-GCM
que proporciona una protección completa contra la manipulación de 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 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 compensarlo, puede desactivar el soporte de verificación de integridad de datos y escribir los archivos cifrados con el algoritmo alternativo
AES-GCM-CTR
, que solo verifica la integridad de partes de los metadatos y no de partes de los datos, y tiene una sobrecarga de rendimiento inferior en comparación con el algoritmoAES-GCM
.parameter name: "encryption.algorithm" parameter value: "AES_GCM_CTR_V1"
Modalidad de pie de página de texto sin formato para los lectores antiguos
De forma predeterminada, el módulo de metadatos de Parquet principal (el pie de página del archivo) se cifra para ocultar el esquema del archivo y la lista de columnas confidenciales. Sin embargo, puede optar por no cifrar los pies de página para permitir que otros lectores de Spark y Parquet (que todavía no dan soporte al cifrado modular de Parquet) puedan leer las columnas no cifradas en los archivos cifrados. Para desactivar el cifrado de pie de página, establezca el parámetro siguiente:
parameter name: "encryption.plaintext.footer" parameter value: "true"
Importante:El parámetro
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 siguientes fragmentos de código de ejemplo para Python muestran cómo crear marcos de datos, escritos en archivos parquet cifrados y leídos de archivos parquet cifrados.
Python: Escritura de datos cifrados:
from pyspark.sql import Row squaresDF = spark.createDataFrame( sc.parallelize(range(1, 6)) .map(lambda i: Row(int_column=i, square_int_column=i ** 2))) sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") sc._jsc.hadoopConfiguration().set("encryption.column.keys", "key1:square_int_column") sc._jsc.hadoopConfiguration().set("encryption.footer.key", "key2") encryptedParquetPath = "squares.parquet.encrypted" squaresDF.write.parquet(encryptedParquetPath)
Python: Lectura de datos cifrados:
sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") encryptedParquetPath = "squares.parquet.encrypted" parquetFile = spark.read.parquet(encryptedParquetPath) parquetFile.show()
El contenido del Python archivo de trabajo InMemoryKMS.py
es el siguiente:
from pyspark.sql import SparkSession
from pyspark import SparkContext
from pyspark.sql import Row
if __name__ == "__main__":
spark = SparkSession \
.builder \
.appName("InMemoryKMS") \
.getOrCreate()
sc = spark.sparkContext
##KMS operation
print("Setup InMemoryKMS")
hconf = sc._jsc.hadoopConfiguration()
encryptedParquetFullName = "testparquet.encrypted"
print("Write Encrypted Parquet file")
hconf.set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==")
btDF = spark.createDataFrame(sc.parallelize(range(1, 6)).map(lambda i: Row(ssn=i, value=i ** 2)))
btDF.write.mode("overwrite").option("encryption.column.keys", "key1:ssn").option("encryption.footer.key", "key2").parquet(encryptedParquetFullName)
print("Read Encrypted Parquet file")
encrDataDF = spark.read.parquet(encryptedParquetFullName)
encrDataDF.createOrReplaceTempView("bloodtests")
queryResult = spark.sql("SELECT ssn, value FROM bloodtests")
queryResult.show(10)
sc.stop()
spark.stop()
Valores internos del manejo de claves de cifrado
Cuando se escribe 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) localmente.
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.
Cuando se lee 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 localmente con la clave de cifrado maestra. Luego la clave de cifrado de datos (DEK) se descifra localmente, utilizando la clave de cifrado por clave (KEK).
Más información
Tema padre: Cuadernos y scripts