Gerenciamento de chave por KMS

A criptografia modular de Parquet pode funcionar com servidores arbitrários do Key Management Service (KMS). Uma classe de cliente customizada do KMS, apta a se comunicar com o servidor KMS escolhido, precisa ser fornecida à instância do Analytics Engine powered by Apache Spark. Essa classe precisa implementar a interface KmsClient (parte da API de criptografia modular do Parquet). O Analytics Engine powered by Apache Spark inclui o VaultClient KmsClient, que poderá ser usado prontamente se você usar o Hashicorp Vault como o servidor KMS para as chaves mestras. Se você usa ou planeja usar um sistema KMS diferente, será possível desenvolver uma classe KmsClient customizada (utilizando o código VaultClient como um exemplo).

Classe KmsClient customizada

A criptografia modular de Parquet fornece uma interface simples chamada org.apache.parquet.crypto.keytools.KmsClient com as duas principais funções a seguir que deve-se implementar:

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

Além disso, a interface fornece a função de inicialização a seguir que transmite parâmetros KMS e outra configuração:

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

Veja Exemplo de implementação KmsClient para saber como implementar um KmsClient.

Depois de ter desenvolvido a classe KmsClient customizada, inclua-a em um jar fornecido no Analytics Engine powered by Apache Spark e transmita seu nome completo na configuração do Spark Hadoop, por exemplo:

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

Gerenciamento de chaves pelo Hashicorp Vault

Se você decidir usar o Hashicorp Vault como o servidor KMS, será possível usar o VaultClient predefinido:

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

Criando chaves mestras

Consulte a documentação do Hashicorp Vault para obter as especificidades sobre ações no Vault. Consulte:

  1. Ative o Mecanismo de Trânsito no caminho padrão ou fornecendo um caminho customizado.
  2. Crie chaves de criptografia nomeadas.
  3. Configure políticas de acesso com as quais um usuário ou máquina tem permissão para acessar essas chaves nomeadas.

Gravando dados criptografados

  1. Transmita os parâmetros a seguir:

    • Configure "parquet.encryption.kms.client.class" para "com.ibm.parquet.key.management.VaultClient":

      sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
      
    • Opcional: Configure o caminho personalizado "parquet.encryption.kms.instance.id" para o seu motor de trânsito:

      sc.hadoopConfiguration.set("parquet.encryption.kms.instance.id" , "north/transit1")
      
    • Configure "parquet.encryption.kms.instance.url" para a URL de sua instância do Vault:

      sc.hadoopConfiguration.set("parquet.encryption.kms.instance.url" , "https://<hostname>:8200")
      
    • Configure o "parquet.encryption.key.access.token" para um token de acesso válido com a política de acesso anexada, que fornece direitos de acesso às chaves necessárias em sua instância do Vault:

      sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
      
    • Se o token estiver localizado em um arquivo local, carregue-o:

      val token = scala.io.Source.fromFile("<token file>").mkStringsc.hadoopConfiguration.set("parquet.encryption.key.access.token" , token)
      
  2. Especifique quais colunas precisam ser criptografadas, e com quais chaves mestras. Também deve-se especificar a chave de rodapé. Por exemplo:

    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>")
    
    Nota:

    Se o parâmetro "parquet.encryption.column.keys" ou "parquet.encryption.footer.key" não estiver definido, será gerado um erro.

Lendo dados criptografados

Os metadados necessários, incluindo o ID e a URL da instância do Hashicorp Vault, são armazenados nos arquivos de Parquet criptografados.

Para ler os metadados criptografados:

  1. Configure o cliente KMS para a implementação do cliente Vault:

    sc.hadoopConfiguration.set("parquet.ecnryption.kms.client.class", "com.ibm.parquet.key.management.VaultClient")
    
  2. Forneça o token de acesso com a política anexada que concede acesso às chaves relevantes:

    sc.hadoopConfiguration.set("parquet.encryption.key.access.token" , "<token string>")
    
  3. Chame os comandos regulares de leitura do Parquet, como:

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

Rotação de chave

Se for necessária uma rotação de chave, um administrador com direitos de acesso às ações de rotação de chaves do KMS deverá girar as chaves mestras no Hashicorp Vault usando o procedimento descrito na documentação do Hashicorp Vault. Depois disso, o administrador pode acionar a rotação da chave do Parquet chamando:

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

Para ativar a rotação de chave do Parquet, as propriedades de configuração do Hadoop a seguir devem ser configuradas:

  • Os parâmetros "parquet.encryption.key.access.token" e "parquet.encryption.kms.instance.url" e opcionalmente "parquet.encryption.kms.instance.id" devem ser configurados
  • O parâmetro "parquet.encryption.key.material.store.internally" deve ser configurado como "false".
  • O parâmetro "parquet.encryption.kms.client.class" deve ser configurado como "com.ibm.parquet.key.management.VaultClient"

Por exemplo:

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)