Si vos données sont stockées sous forme de colonnes, vous pouvez utiliser le chiffrement modulaire Parquet pour chiffrer les colonnes sensibles lors de l'écriture des fichiers Parquet et déchiffrer ces colonnes lors de la lecture des fichiers chiffrés. Le chiffrement des données au niveau des colonnes permet de déterminer les colonnes à chiffrer et de contrôler l'accès aux colonnes.
En plus de garantir la confidentialité des données, le chiffrement modulaire Parquet protège l'intégrité des données stockées. Toute altération du contenu des fichiers est détectée et déclenche une exception côté lecture.
Principales caractéristiques :
Le chiffrement et le déchiffrement modulaire Parquet sont effectués sur le cluster Spark. Par conséquent, les données sensibles et les clés de chiffrement ne sont pas visibles par le stockage.
Les fonctionnalités standard de Parquet, telles que l'encodage, la compression, la projection colonnaire et le "predicate push-down", continuent à fonctionner de la même manière sur les fichiers au format à chiffrement modulaire Parquet.
Vous pouvez choisir l'un des deux algorithmes de chiffrement définis dans la spécification Parquet. Les deux algorithmes se prêtent au chiffrement de colonnes, mais :
AES-GCM
, l'algorithme par défaut, assure une protection totale contre l'altération des données et des parties métadonnées dans les fichiers Parquet.- L'autre algorithme,
AES-GCM-CTR
, assure une protection partielle de l'intégrité des fichiers Parquet. Seules les parties métadonnées, et non les parties données, sont protégées contre la falsification. L'avantage de cet algorithme par rapport àAES-GCM
est qu'il pénalise moins le débit de traitement.
Vous pouvez choisir quelles colonnes sont à chiffrer. Les autres colonnes ne seront pas chiffrées, ce qui réduit le temps système de traitement.
Différentes colonnes peuvent être chiffrées avec des clés différentes.
Par défaut, le module de métadonnées principal Parquet (le pied de page du fichier) est chiffré pour masquer le schéma du fichier et la liste des colonnes sensibles. Cependant, vous pouvez choisir de ne pas chiffrer les cartouches de fichier afin de permettre aux anciens lecteurs (comme les autres distributions Spark qui ne prennent pas encore en charge le chiffrement modulaire par le Parquet) de lire les colonnes non chiffrées dans les fichiers cryptés.
Les clés de chiffrement peuvent être gérées de deux manières :
- Directement par votre application. Consultez Gestion des clés par l'application.
- Par un système de gestion de clés (KMS) qui génère, stocke et détruit les clés de chiffrement utilisées par le service Spark. Ces clés ne quittent jamais le serveur KMS, par conséquent, elles sont invisibles pour les autres composants, y compris le service Spark. Voir Gestion des clés par KMS.
Remarque : seules les clés de chiffrement principales (MEK) doivent être gérées par votre application ou par un système KMS.
Pour chaque colonne sensible, vous devez indiquer quelle clé principale utiliser pour le chiffrement. Une clé principale doit aussi être spécifiée pour le pied de page (footer) de chaque fichier chiffré (data frame). Par défaut, la clé du pied de page sera utilisée pour le chiffrement du pied de page. Si toutefois vous optez pour le mode pied de page en clair, le pied de page ne sera pas chiffré et la clé ne sera utilisée que pour vérifier l'intégrité du pied de page.
Les paramètres de chiffrement peuvent être passés par l'intermédiaire de la configuration standard Hadoop Spark, par exemple en spécifiant leurs valeurs dans la configuration Hadoop du contexte Spark de l'application :
sc.hadoopConfiguration.set("<parameter name>" , "<parameter value>")
Vous pouvez aussi passer des valeurs de paramètre via les options d'écriture (write) :
<data frame name>.write .option("<parameter name>" , "<parameter value>") .parquet("<write path>")
Exécution avec le chiffrement modulaire Parquet
Le chiffrement modulaire Parquet est disponible uniquement dans les blocs-notes Spark qui s'exécutent dans une instance de service IBM Analytics Engine. Il n'est pas pris en charge dans les blocs-notes qui s'exécutent dans un environnement Spark.
Pour activer le chiffrement modulaire Parquet, définissez les propriétés de chemin d'accès aux classes Spark suivantes pour qu'elles pointent vers les fichiers JAR Parquet qui implémentent le chiffrement modulaire Parquet et vers le fichier JAR de gestion des clés :
Naviguez jusqu'à Ambari > Spark > Config -> Custom spark2-default.
Ajoutez les deux paramètres suivants pour pointer explicitement sur l'emplacement des fichiers JAR. Veillez à éditer les chemins afin d'y indiquer la bonne version des fichiers jar présents sur le cluster.
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
Paramètres obligatoires
Les paramètres suivants sont obligatoires pour écrire des données chiffrées :
Liste des colonnes à chiffrer, avec les clés de chiffrement maître :
parameter name: "encryption.column.keys" parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.."
Clé de pied de page :
parameter name: "encryption.footer.key" parameter value: "<master key ID>"
Par exemple :
dataFrame.write .option("encryption.footer.key" , "k1") .option("encryption.column.keys" , "k2:SSN,Address;k3:CreditCard") .parquet("<path to encrypted files>")
Important :Si ni le paramètre
encryption.column.keys
ni le paramètreencryption.footer.key
ne sont définis, le fichier n'est pas chiffré. Si un seul de ces paramètres est défini, une exception est générée car ces paramètres sont obligatoires pour les fichiers chiffrés.
Paramètres optionnels
Les paramètres optionnels suivants peuvent être utilisés lors de l'écriture de données chiffrées :
L'algorithme de chiffrement
AES-GCM-CTR
Par défaut, le chiffrement modulaire du parquet utilise l'algorithme
AES-GCM
qui offre une protection complète contre l'altération des données et des métadonnées dans les fichiers Parquet. Cependant, étant donné que Spark 2.3.0 fonctionne sur Java 8, qui ne reconnaît pas l'accélération matérielle d'AES dans le processeur (le support de celle-ci n'ayant été ajouté que dans Java 9), le surcroît de traitement nécessaire à la vérification de l'intégrité des données peut affecter la vitesse de traitement de la charge de travail dans certains cas.Pour contrebalancer ce point, vous pouvez mettre hors fonction le support de vérification de l'intégrité des données et utiliser l'autre algorithme,
AES-GCM-CTR
, pour écrire les fichiers chiffrés. L'avantage de cet algorithme par rapport àAES-GCM
est qu'il pénalise moins le débit de traitement, car il vérifie seulement les parties métadonnées, et non les parties données.parameter name: "encryption.algorithm" parameter value: "AES_GCM_CTR_V1"
Mode pied de page en clair pour les anciens lecteurs
Par défaut, le module de métadonnées principal Parquet (le pied de page du fichier) est chiffré pour masquer le schéma du fichier et la liste des colonnes sensibles. Cependant, vous pouvez décider de ne pas chiffrer les pieds de page afin de permettre à d'autres lecteurs Spark et Parquet (qui ne prennent pas encore en charge le chiffrement modulaire Parquet) de lire les colonnes non chiffrées dans les fichiers cryptés. Pour désactiver le chiffrement des pieds de page, définissez le paramètre suivant :
parameter name: "encryption.plaintext.footer" parameter value: "true"
Important :Le paramètre
encryption.footer.key
doit également être spécifié dans le mode de bas de page en texte en clair. Bien que le pied de page ne soit pas chiffré, la clé est utilisée pour signer le contenu du pied de page, ce qui signifie que les nouveaux lecteurs peuvent vérifier son intégrité. Les lecteurs existants ne sont pas affectés par l'ajout de la signature du pied de page.
Exemples d'utilisation
Les exemples de fragments de code suivants pour Python montrent comment créer des cadres de données, écrits dans des fichiers parquet chiffrés et lus à partir de fichiers parquet chiffrés.
Python : écriture de données chiffrées :
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 : lecture de données chiffrées :
sc._jsc.hadoopConfiguration().set("encryption.key.list", "key1: AAECAwQFBgcICQoLDA0ODw==, key2: AAECAAECAAECAAECAAECAA==") encryptedParquetPath = "squares.parquet.encrypted" parquetFile = spark.read.parquet(encryptedParquetPath) parquetFile.show()
Le contenu du fichier de travail Python InMemoryKMS.py
est le suivant:
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()
Aspects internes du traitement des clés de chiffrement
Lors de l'écriture d'un fichier Parquet, une clé de chiffrement de données (DEK, data encryption key) aléatoire est générée pour chaque colonne chiffrée ainsi que pour le pied de page (footer). Ces clés sont utilisées pour chiffrer les données et les modules de métadonnées dans le fichier Parquet.
La clé de chiffrement de données est alors chiffrée avec une clé de chiffrement de clé (KEK, key encryption key), laquelle est également générée à l'intérieur de Spark/Parquet pour chaque clé principale. La clé de chiffrement de clé est déchiffrée localement à l'aide d'une clé de chiffrement principale (MEK).
Les clés de chiffrement de données et les clés de chiffrement de clé chiffrées sont stockées dans les métadonnées du fichier Parquet, conjointement avec l'identité de la clé principale. Chaque clé de chiffrement de clé a une identité unique (générée localement sous la forme d'une valeur aléatoire sûre à 16 octets), également stockée dans les métadonnées du fichier.
Lors de la lecture d'un fichier Parquet, l'identificateur de la clé de chiffrement principale (MEK) et la clé de chiffrement de clé (KEK) chiffrée accompagnée de son identificateur, ainsi que la clé de chiffrement de données (DEK) chiffrée, sont extraits des métadonnées du fichier.
La clé de chiffrement de clé est déchiffrée à l'aide de la clé de chiffrement principale en local. La clé de chiffrement de données (DEK) sera décryptée localement, au moyen de la clé de chiffrement de clé (KEK).
En savoir plus
Rubrique parent: Blocs-notes et scripts