Mit modularer Parquet-Verschlüsselung arbeiten

IBM Analytics Engine Serverless unterstützt die modulare Parquet-Verschlüsselung, eine neue Ergänzung zum Parquet-Standard, die die Verschlüsselung sensibler Spalten beim Schreiben von Parquet-Dateien und die Entschlüsselung dieser Spalten beim Lesen der verschlüsselten Dateien ermöglicht. Siehe Modulare Parquet-Verschlüsselung.

Parquet schützt nicht nur personenbezogene Daten, sondern auch die Integrität der gespeicherten Daten. Manipulationen von Dateiinhalten werden erkannt und ggf. wird eine readerseitige Ausnahmebedingung ausgelöst.

Einige der Schlüsselfunktionen sind:

  1. Parquet-Verschlüsselung und -Entschlüsselung wird in den Spark-Workern ausgeführt. Daher sind sensible Daten und die Verschlüsselungsschlüssel nicht im Speicher sichtbar.

  2. Parquet-Standardfeatures, wie Verschlüsselung, Komprimierung, Spaltenprojektion und Prädikatübertragung im Pushdown-Modus, funktionieren für Dateien mit modularem Parquet-Verschlüsselungsformat weiterhin wie gewohnt.

  3. Sie können einen der beiden in der Parquet-Spezifikation definierten Verschlüsselungsalgorithmen auswählen. Beide Algorithmen unterstützen die Spaltenverschlüsselung. Jedoch muss Folgendes beachtet werden:

    • Der Standardalgorithmus AES-GCM bietet vollständigen Schutz vor der Manipulation von Daten- und Metadatenteilen in Parquet-Dateien.
    • Der alternative Algorithmus AES-GCM-CTR unterstützt den Teilintegritätsschutz von Parquet-Dateien. Nur Metadatenteile werden vor Manipulation geschützt, Datenteile nicht. Ein Vorteil dieses Algorithmus im Vergleich zum Algorithmus AES-GCM ist der geringere Durchsatzaufwand.
  4. Sie können auswählen, welche Spalten verschlüsselt werden sollen. Andere Spalten werden nicht verschlüsselt, wodurch der Durchsatzaufwand reduziert wird.

  5. Unterschiedliche Spalten können mit unterschiedlichen Schlüsseln verschlüsselt werden.

  6. Standardmäßig ist das Parquet-Hauptmetadatenmodul (der Dateifooter) verschlüsselt, um das Dateischema und die Liste der sensiblen Spalten auszublenden. Sie können jedoch auswählen, dass die Dateifooter nicht verschlüsselt werden, damit traditionelle Reader (wie z. B. andere Spark-Distributionen, die noch keine Parquet-Verschlüsselung unterstützen) die nicht verschlüsselten Spalten in den verschlüsselten Dateien lesen können.

  7. Verschlüsselungsschlüssel können mit einer der folgenden Methoden verwaltet werden:

    IBM® Key Protect for IBM Cloud® hilft Ihnen durch die Ausrichtung an IBM Cloud-IAM-Rollen (Identity and Access Management) beim Verwalten Ihrer verschlüsselten Schlüssel.

    Hinweis: Nur Masterverschlüsselungsschlüssel (MEK - Master Encryption Keys) müssen verwaltet werden (über Ihre Anwendung oder über Key Protect). Datenverschlüsselungsschlüssel (DEK - Data Encryption Key) werden von Spark/Parquet automatisch bearbeitet. Details zur Handhabung von Schlüsseln in der Parquet-Verschlüsselung finden Sie in Interne Details zur Handhabung von Verschlüsselungsschlüsseln.

    Sie müssen für jede Spalte mit sensiblen Daten angeben, welcher Masterschlüssel für die Verschlüsselung verwendet werden soll. Außerdem muss ein Masterschlüssel für die Fußzeile jeder verschlüsselten Datei (Datenrahmen) angegeben werden, da die Fußzeilen Metadaten wie das Schema und die Liste sensibler Spalten enthalten, die auch sensibel sein können. Standardmäßig wird der Footerschlüssel für die Footerverschlüsselung verwendet. Wenn Sie jedoch einen Klartextmodus für den Footer auswählen, wird der Schlüssel nur zur Prüfung der Footerintegrität verwendet.

    Die Verschlüsselungsparameter können über die Spark Hadoop-Standardkonfiguration übergeben werden, beispielsweise durch Festlegen der Konfigurationswerte für den Spark-Kontext (SparkContext) in der Hadoop-Konfiguration:

    sc.hadoopConfiguration.set("<parameter name>" , "<parameter value>")
    

    Alternativ können Sie Parameterwerte über Schreiboptionen übergeben:

    <data frame name>.write
    .option("<parameter name>" , "<parameter value>")
    .parquet("<write path>")
    

Obligatorische Parameter für die Ausführung mit Parquet-Verschlüsselung

Die folgenden Parameter sind zum Schreiben verschlüsselter Daten erforderlich:

  • Liste zu verschlüsselnder Spalten einschließlich Masterverschlüsselungsschlüsseln:

    parameter name: "parquet.encryption.column.keys"
    parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.."
    
  • Fußzeilenschlüssel:

    parameter name: "parquet.encryption.footer.key"
    parameter value: "<master key ID>"
    

    Beispiel:

    dataFrame.write
    .option("parquet.encryption.footer.key" , "k1")
    .option("parquet.encryption.column.keys" , "k2:SSN,Address;k3:CreditCard")
    .parquet("<path to encrypted files>")
    

    Wichtig: Wenn weder der Parameter "parquet.encryption.column.keys" noch der "parquet.encryption.footer.key" -Parameter festgelegt ist, wird die Datei nicht verschlüsselt. Wenn nur einer dieser Parameter gesetzt ist, wird eine Ausnahmebedingung ausgelöst, da diese Parameter für verschlüsselte Dateien obligatorisch sind.

  • Die Klasse, die EncryptionPropertiesFactory implementiert:

    parameter name: "parquet.crypto.factory.class"
    parameter value: "com.ibm.parquet.key.management.IBMKeyToolsFactory"
    

    Wichtig: Wenn "parquet.crypto.factory.class" nicht festgelegt ist, wird die Datei von einer Verschlüsselungsfactory nicht verschlüsselt.

Optionale Parameter

Die folgenden optionalen Parameter können beim Schreiben verschlüsselter Daten verwendet werden:

  • Der Verschlüsselungsalgorithmus AES-GCM-CTR

    Die Parquet-Verschlüsselung verwendet standardmäßig den Algorithmus AES-GCM, der umfassenden Schutz vor der Manipulation von Daten und Metadaten in Parquet-Dateien bietet. Da Spark 2.3.0 jedoch unter Java 8 ausgeführt wird, das die AES-Beschleunigung in der CPU-Hardware nicht unterstützt (dies wurde erst in Java 9 hinzugefügt), kann der Aufwand für die Prüfung der Datenintegrität sich in bestimmten Situationen auf den Workloaddurchsatz auswirken.

    Um dies zu kompensieren, können Sie die Unterstützung für die Datenintegritätsprüfung ausschalten und die verschlüsselten Dateien mit dem alternativen Algorithmus AES-GCM-CTR schreiben, der nur die Integrität der Metadatenteile und nicht die der Datenteile überprüft und im Vergleich zum Algorithmus AES-GCM einen geringeren Durchsatzaufwand aufweist.

    parameter name: "parquet.encryption.algorithm"
    parameter value: "AES_GCM_CTR_V1"
    
  • Klartextmodus für den Footer für traditionelle Reader

    Standardmäßig ist das Parquet-Hauptmetadatenmodul (der Dateifooter) verschlüsselt, um das Dateischema und die Liste der sensiblen Spalten auszublenden. Sie können sich jedoch auch dafür entscheiden, die Dateifooter nicht zu verschlüsseln, um anderen Spark- und Parquet-Readern (die die Parquet-Verschlüsselung bisher noch nicht unterstützen) das Lesen der nicht verschlüsselten Spalten in den verschlüsselten Dateien zu ermöglichen. Setzen Sie die folgenden Parameter, um die Footerverschlüsselung auszuschalten:

    parameter name: "parquet.encryption.plaintext.footer"
    parameter value: "true"
    

    Wichtig: Der Parameter "parquet.encryption.footer.key" muss auch im Fußzeilenmodus für einfachen Text angegeben werden. Die Fußzeile ist zwar nicht verschlüsselt, aber der Schlüssel wird zum Signieren des Fußzeileninhalts verwendet. Neue Reader könnten also seine Integrität prüfen. Das Hinzufügen der Fußzeilensignatur hat keine Auswirkungen auf traditionelle Reader.

Verwendungsbeispiele

Die folgenden Beispiel-Code-Snippets für Python und Scala veranschaulichen, wie DataFrames erstellt, in verschlüsselte Parquet-Dateien geschrieben und aus verschlüsselten Parquet-Dateien gelesen werden.

  • Python: Verschlüsselte Daten schreiben

    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: Verschlüsselte Daten lesen

    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: Verschlüsselte Daten schreiben

    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: Verschlüsselte Daten lesen

    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()
    

Interne Details zur Handhabung von Verschlüsselungsschlüsseln

Beim Schreiben einer Parquet-Datei wird für jede verschlüsselte Spalte sowie für den Footer ein zufälliger Datenverschlüsselungsschlüssel (DEK - Data Encryption Key) generiert. Diese Schlüssel werden zum Verschlüsseln der Daten und der Metadatenmodule in der Parquet-Datei verwendet.

Der Datenverschlüsselungsschlüssel wird dann mit einem Schlüsselverschlüsselungsschlüssel (KEK - Key Encryption Key) verschlüsselt, der in Spark/Parquet für jeden Masterschlüssel generiert wird. Der Schlüsselverschlüsselungsschlüssel wird mit einem Masterverschlüsselungsschlüssel (MEK - Master Encryption Key) verschlüsselt. Dies erfolgt lokal, wenn die Masterschlüssel von der Anwendung verwaltet werden, oder in einem KeyProtect-Service, wenn die Masterschlüssel von IBM® Key Protect for IBM Cloud® verwaltet werden.

Verschlüsselte Daten- und Schlüsselverschlüsselungsschlüssel werden zusammen mit der Masterschlüsselidentität in den Parquet-Dateimetadaten gespeichert. Jeder Schlüsselverschlüsselungsschlüssel hat eine eindeutige Identität, die lokal als sicherer zufälliger 16-Byte-Wert generiert und ebenfalls in den Dateimetadaten gespeichert wird. Schlüsselverschlüsselungsschlüssel werden vom Zugriffstoken zwischengespeichert, sodass keine Interaktion mit dem KeyProtect-Service für jede verschlüsselte Spalte oder Datei erforderlich ist, wenn sie denselben Masterverschlüsselungsschlüssel verwenden.

Wenn eine Parquet-Datei gelesen wird, werden die Kennung des Masterverschlüsselungsschlüssels (MEK), der verschlüsselte Schlüsselverschlüsselungsschlüssel (KEK) mit seiner Kennung und der verschlüsselte Datenverschlüsselungsschlüssel (DEK) aus den Dateimetadaten extrahiert.

Der Schlüsselverschlüsselungsschlüssel wird mit dem Masterverschlüsselungsschlüssel entschlüsselt. Dies erfolgt lokal, wenn die Masterschlüssel von der Anwendung verwaltet werden, oder in einem KeyProtect-Service, wenn die Masterschlüssel von IBM® Key Protect for IBM Cloud® verwaltet werden. Die Schlüsselverschlüsselungsschlüssel werden vom Zugriffstoken zwischengespeichert, sodass es nicht erforderlich ist, für jede entschlüsselte Spalte oder Datei mit dem KeyProtect-Service zu interagieren, wenn sie denselben Schlüsselverschlüsselungsschlüssel verwenden. In diesem Fall wird der Datenverschlüsselungsschlüssel (Data Encryption Key - DEK) lokal mithilfe des Schlüsselverschlüsselungsschlüssels (Key Encryption Key - KEK) entschlüsselt.

Schlüsselrotation (optionale Funktion)

Das Verfahren zur Envelope-Verschlüsselung bietet eine erweiterte Option für den turnusmäßigen Wechsel von Masterschlüsseln, um das Risiko von Datenlecks sensibler Daten aufgrund beeinträchtigter MEKs zu minimieren. DEKs können nicht geändert werden, da dies bedeutet, dass die Parquet-Dateien vollständig erneut verschlüsselt werden. Die neuen MEKs (und transparent neu generierte KEKs) werden zum erneuten Verschlüsseln der DEKs verwendet.

Um die Schlüsselrotation in Parquet-Dateien zu ermöglichen, muss der Parameter "parquet.encryption.key.material.store.internally" beim Schreiben der Parquet-Dateien in der Hadoop-Konfiguration auf "false" gesetzt werden.

Mit diesem Parametersatz speichert Parquet die Schlüssel (mit MEKs eingeschlossen) in separaten kleinen Dateien und nicht in den Parquet-Dateien. Bei der Schlüsselrotation werden nur die kleinen Schlüsselmaterialdateien ersetzt. Keine Notwendigkeit, die Parquet-Dateien zu ändern (die häufig unveränderlich sind). Die meisten KMS-Systeme unterstützen die Schlüsselrotation, indem sie den Inhalt der gespeicherten Masterschlüssel ersetzen und die MEK-ID intakt halten (aber die Schlüsselversion aktualisieren). Nachdem ein Benutzer oder Administrator die Masterschlüsselrotation innerhalb der KMS-Instanz mithilfe der KMS-spezifischen API ausgeführt hat, kann der Parquet-Schlüsselrotationsmechanismus ausgelöst werden (beispielsweise durch denselben Administrator), indem Folgendes aufgerufen wird:

public static void KeyToolkit.rotateMasterKeys(String folderPath, Configuration hadoopConfig)

Wenn die Schlüsselrotation ausgeführt wird, wird für jeden Schlüsselschlüssel in allen Schlüsselmaterialdateien in folderPath das Wrapping mit der alten MEK-Version aufgehoben, um die Entschlüsselung des DEK zu ermöglichen. Für jede Masterschlüssel-ID wird ein neuer KEK generiert und mit der neuen MEK-Version eingeschlossen. Die Erstellung eines neuen KEK anstelle der Wiederverwendung des alten KEK bedeutet nicht nur, dass die Sicherheit verbessert wird, sondern auch, dass die Leistung nachfolgender Datenleseoperationen erhöht wird. Dies liegt daran, dass ein einzelner Schlüsselrotationsprozess, der vom Administrator ausgeführt wird, über mehrere Dateien hinweg ausgeführt wird, die von verschiedenen Prozessen erstellt wurden, was bedeutet, dass viele verschiedene KEKs für dieselbe MEK-ID verwendet werden. Der Schlüsselrotationsprozess ersetzt die alten KEKs durch einen einzigen neuen KEK, der es den Lesern ermöglicht, für jeden Masterschlüssel eine einzelne Unwrapping-Interaktion mit KMS auszuführen.

Beispiele für die Verwendung der Schlüsselrotation:

Weitere Informationen

Sehen Sie sich das folgende Beispielnotebook an, um sich mit der Verwendung der Parquet-Verschlüsselung vertraut zu machen: