Schlüsselmanagement mit KMS

Die modulare Parquet-Verschlüsselung kann mit beliebigen KMS-Servern (KMS = Key Management Service) zusammenarbeiten. Eine angepasste KMS-Clientklasse, die mit dem ausgewählten KMS-Server kommunizieren kann, muss für die Analytics Engine powered by Apache Spark-Instanz bereitgestellt werden. Diese Klasse muss die KmsClient-Schnittstelle (Bestandteil der API der modularen Parquet-Verschlüsselung) implementieren. Analytics Engine powered by Apache Spark beinhaltet die Komponente VaultClient KmsClient, die sofort einsatzfähig ist, wenn Hashicorp Vault als KMS-Server für die Masterschlüssel verwendet wird. Wenn Sie ein anderes KMS-System verwenden oder verwenden möchten, können Sie eine angepasste Klasse KmsClient entwickeln (nach dem Beispiel des VaultClient-Codes).

Angepasste Klasse KmsClient

Die modulare Parquet-Verschlüsselung stellt eine einfache Schnittstelle namens org.apache.parquet.crypto.keytools.KmsClient mit den folgenden zwei Hauptfunktionen bereit, die Sie implementieren müssen:

// Wraps a key - encrypts it with the master key, encodes the result and
// potentially adds KMS-specific metadata.
public String wrapKey(byte[] keyBytes, String masterKeyIdentifier)
// Decrypts (unwraps) a key with the master key.
public byte[] unwrapKey(String wrappedKey, String masterKeyIdentifier)

Darüber hinaus stellt die Schnittstelle die folgende Initialisierungsfunktion bereit, die KMS-Parameter und weitere Konfigurationseinstellungen übergibt.

public void initialize(Configuration configuration, String kmsInstanceID, String kmsInstanceURL, String accessToken)

Informationen zum Implementieren eines KmsClient finden Sie unter Beispiel für KmsClient-Implementierung.

Nachdem Sie die angepasste KmsClient-Klasse entwickelt haben, fügen Sie sie zu einer JAR-Datei hinzu, die der Analytics Engine powered by Apache Spark zur Verfügung gestellt wird, übergeben Sie den vollständigen Namen an die Spark-Hadoop-Konfiguration, wie im folgenden Beispiel:

sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "full.name.of.YourKmsClient"

Schlüsselmanagement mit Hashicorp Vault

Wenn Sie Hashicorp Vault als KMS-Server verwenden möchten, können Sie das vordefinierte Element VaultClient verwenden:

sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")

Masterschlüssel erstellen

In der Hashicorp Vault-Dokumentation finden Sie die Details zu den Aktionen für die Vault. Siehe:

  1. Aktivieren Sie die Transit-Engine im Standardpfad oder geben Sie einen angepassten Pfad an.
  2. Erstellen Sie benannte Verschlüsselungsschlüssel.
  3. Konfigurieren Sie Zugriffsrichtlinien, die einem Benutzer oder einer Maschine den Zugriff auf diese benannten Schlüssel ermöglichen.

Verschlüsselte Daten schreiben

  1. Übergeben Sie die folgenden Parameter:

    • Setzen Sie "parquet.encryption.kms.client.class" auf "com.ibm.parquet.key.management.VaultClient":

      sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
      
    • Optional: Legen Sie den angepassten Pfad "parquet.encryption.kms.instance.id" für Ihre Transit-Engine fest:

      sc.hadoopConfiguration.set("parquet.encryption.kms.instance.id" , "north/transit1")
      
    • Setzen Sie "parquet.encryption.kms.instance.url" auf die URL Ihrer Vault-Instanz:

      sc.hadoopConfiguration.set("parquet.encryption.kms.instance.url" , "https://<hostname>:8200")
      
    • Legen Sie für "parquet.encryption.key.access.token" ein gültiges Zugriffstoken mit der zugeordneten Zugriffsrichtlinie fest, das Zugriffsberechtigungen für die erforderlichen Schlüssel in Ihrer Vault-Instanz bereitstellt:

      sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
      
    • Wenn das Token in einer lokalen Datei enthalten ist, laden Sie es:

      val token = scala.io.Source.fromFile("<token file>").mkStringsc.hadoopConfiguration.set("parquet.encryption.key.access.token" , token)
      
  2. Geben Sie an, welche Spalten mit welchen Masterschlüsseln verschlüsselt werden müssen. Sie müssen auch den Fußzeilenschlüssel angeben. Zum Beispiel:

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

    Wenn entweder der "parquet.encryption.column.keys" oder der "parquet.encryption.footer.key" Parameter nicht gesetzt ist, wird ein Fehler erzeugt.

Verschlüsselte Daten lesen

Die erforderlichen Metadaten, einschließlich ID und URL der Hashicorp Vault-Instanz werden in den verschlüsselten Parquet-Dateien gespeichert.

Gehen Sie wie folgt vor, um die verschlüsselten Metadaten zu lesen:

  1. Geben Sie als KMS-Client die Vault-Clientimplementierung an:

    sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
    
  2. Geben Sie das Zugriffstoken mit angehängter Richtlinie an, die den Zugriff auf die relevanten Schlüssel erteilt:

    sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
    
  3. Rufen Sie die regulären Parquet-Lesebefehle auf. Beispiel:

    val dataFrame = spark.read.parquet("<path to encrypted files>")
    

Schlüsselrotation

Falls die Schlüsselrotation erforderlich ist, muss ein Administrator mit Zugriffsrechten für die Aktionen der KMS-Schlüsselrotation die Rotation der Masterschlüssel in Hashicorp Vault mithilfe der in der Hashicorp Vault-Dokumentation beschriebenen Prozedur durchführen. Anschließend kann der Administrator die Parquet-Schlüsselrotation mit dem folgenden Aufruf auslösen:

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

Zum Aktivieren der Parquet-Schlüsselrotation müssen die folgenden Hadoop-Konfigurationseigenschaften festgelegt werden:

  • Die Parameter "parquet.encryption.key.access.token" und "parquet.encryption.kms.instance.url" und optional "parquet.encryption.kms.instance.id" müssen festgelegt werden.
  • Der Parameter "parquet.encryption.key.material.store.internally" muss auf "false" gesetzt werden.
  • Der Parameter "parquet.encryption.kms.client.class"muss auf "com.ibm.parquet.key.management.VaultClient"gesetzt werden.

Zum Beispiel:

sc.hadoopConfiguration.set("parquet.encryption.kms.instance.url" , "https://<hostname>:8200")sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
sc.hadoopConfiguration.set("parquet.encryption.kms.client.class","com.ibm.parquet.key.management.VaultClient")
sc.hadoopConfiguration.set("parquet.encryption.key.material.store.internally", "false")
KeyToolkit.rotateMasterKeys("<path to encrypted files>", sc.hadoopConfiguration)