Trabalhando com a criptografia modular do Parquet
IBM Analytics Engine Serverless suporta a criptografia modular do Parquet, uma nova adição ao padrão do Parquet que permite criptografar colunas sensíveis ao gravar arquivos Parquet e decriptografar essas colunas ao ler os arquivos criptografados. Veja criptografia modular de Parquet.
Além de garantir a privacidade, a criptografia do Parquet também protege a integridade dos dados armazenados. Qualquer violação no conteúdo do arquivo é detectada e aciona uma exceção do lado do leitor.
Os principais recursos incluem:
-
A criptografia e a decriptografia do Parquet são realizadas nos trabalhadores do Spark. Portanto, os dados sensíveis e as chaves de criptografia não são visíveis para o armazenamento.
-
Os recursos do Parquet padrão, como codificação, compactação, projeção colunas e push-down de predicado, continuam a funcionar como de costume nos arquivos com formato de criptografia modular do Parquet.
-
É possível escolher um dos dois algoritmos de criptografia que são definidos na especificação do Parquet. Os dois algoritmos suportam a criptografia de coluna, no entanto:
- O algoritmo padrão
AES-GCMfornece proteção total contra a violação de dados e de partes de metadados em arquivos Parquet. - O algoritmo alternativo
AES-GCM-CTRsuporta a proteção da integridade parcial de arquivos Parquet. Apenas as partes de metadados são protegidas contra adulteração, não as partes de dados. Uma vantagem desse algoritmo é que ele tem uma sobrecarga de rendimento inferior em comparação com o algoritmoAES-GCM.
- O algoritmo padrão
-
É possível escolher quais colunas deseja criptografar. As outras colunas não serão criptografadas, reduzindo a sobrecarga de rendimento.
-
Colunas diferentes podem ser criptografadas com chaves diferentes.
-
Por padrão, o módulo de metadados do Parquet principal (o rodapé do arquivo) é criptografado para ocultar o esquema de arquivo e a lista de colunas sensíveis. No entanto, é possível optar por não criptografar os rodapés do arquivo para permitir que os leitores anteriores (como outras distribuições do Spark que ainda não suportam a criptografia do Parquet) leiam as colunas não criptografadas nos arquivos criptografados.
-
As chaves de criptografia podem ser gerenciadas de uma das duas maneiras:
- Diretamente por seu aplicativo. Veja Gerenciamento de chaves por aplicativo.
- Pelo IBM® Key Protect for IBM Cloud®, um sistema de gerenciamento de chaves centralizado (KMS) para geração, gerenciamento e destruição das chaves de criptografia usadas por IBM Analytics Engine. Consulte Gerenciamento de chave por Key Protect{: {: external}}.
O IBM® Key Protect for IBM Cloud® ajuda a gerenciar suas chaves criptografadas, alinhando com as funções de Identidade e Gerenciamento de Acesso (IAM) do IBM Cloud.
Nota: apenas as chaves mestras de criptografia (MEKs) precisam ser gerenciadas (seja pelo aplicativo ou pelo Key Protect). As chaves de criptografia de dados (DEKs) são manipuladas automaticamente pelo Spark/Parquet. Para obter detalhes sobre a manipulação de chave dentro da criptografia do Parquet, consulte Atividades internas de manipulação de chaves de criptografia.
Para cada coluna sensível, deve-se especificar qual chave mestra usar para criptografia. Além disso, uma chave principal deve ser especificada para o rodapé de cada arquivo criptografado (dataframe), pois os rodapés mantêm metadados como esquema e lista de colunas sensíveis, que podem ser sensíveis também. Por padrão, a chave de rodapé será usada para a criptografia do rodapé. No entanto, se você escolher um modo de rodapé de texto sem formatação, o rodapé não será criptografado e a chave será usada apenas para verificação de integridade do rodapé.
Os parâmetros de criptografia podem ser passados pela configuração padrão do Spark Hadoop, por exemplo, definindo os valores de configuração na configuração do Hadoop do SparkContext do aplicativo:
sc.hadoopConfiguration.set("<parameter name>" , "<parameter value>")Como alternativa, é possível transmitir valores de parâmetro por opções de gravação:
<data frame name>.write .option("<parameter name>" , "<parameter value>") .parquet("<write path>")
Parâmetros obrigatórios para execução com criptografia de Parquet
Os parâmetros a seguir são necessários para gravar dados criptografados:
-
Lista de colunas a serem criptografadas, com as chaves mestras de criptografia:
parameter name: "parquet.encryption.column.keys" parameter value: "<master key ID>:<column>,<column>;<master key ID>:<column>,.." -
A chave de rodapé:
parameter name: "parquet.encryption.footer.key" parameter value: "<master key ID>"Por exemplo:
dataFrame.write .option("parquet.encryption.footer.key" , "k1") .option("parquet.encryption.column.keys" , "k2:SSN,Address;k3:CreditCard") .parquet("<path to encrypted files>")Importante: se nem o parâmetro
"parquet.encryption.column.keys"nem o parâmetro"parquet.encryption.footer.key"estiver configurado, o arquivo não será criptografado. Se apenas um desses parâmetros for configurado, uma exceção será lançada, pois esses parâmetros são obrigatórios para arquivos criptografados. -
A classe implementa
EncryptionPropertiesFactory:parameter name: "parquet.crypto.factory.class" parameter value: "com.ibm.parquet.key.management.IBMKeyToolsFactory"Importante: Se
"parquet.crypto.factory.class"não for configurado, o arquivo não será criptografado por uma fábrica de criptomos.
Parâmetros opcionais
Os parâmetros opcionais a seguir podem ser usados ao gravar dados criptografados:
-
O algoritmo de criptografia
AES-GCM-CTRPor padrão, a criptografia do Parquet usa o algoritmo
AES-GCM, que fornece proteção total contra a violação de dados e metadados em arquivos do Parquet. No entanto, como o Spark 2.3.0 é executado no Java 8, que não suporta a aceleração de AES em hardware de CPU (isso foi incluído apenas no Java 9), a sobrecarga de verificação de integridade de dados pode afetar o rendimento da carga de trabalho em determinadas situações.Para compensar isso, é possível desativar o suporte de verificação de integridade de dados e gravar os arquivos criptografados com o algoritmo alternativo
AES-GCM-CTR, que verifica a integridade apenas das partes de metadados e não das partes de dados e tem uma sobrecarga de rendimento inferior em comparação com o algoritmoAES-GCM.parameter name: "parquet.encryption.algorithm" parameter value: "AES_GCM_CTR_V1" -
Modo de rodapé de texto sem formatação para leitores anteriores
Por padrão, o módulo de metadados do Parquet principal (o rodapé do arquivo) é criptografado para ocultar o esquema de arquivo e a lista de colunas sensíveis. No entanto, é possível decidir não criptografar os rodapés do arquivo a fim de possibilitar que outros leitores do Spark e do Parquet (que ainda não suportam a criptografia do Parquet) leiam as colunas não criptografadas nos arquivos criptografados. Para alternar a criptografia de rodapé, configure o seguinte parâmetro:
parameter name: "parquet.encryption.plaintext.footer" parameter value: "true"Importante: o parâmetro
"parquet.encryption.footer.key"também deve ser especificado no modo de rodapé de texto sem formatação. Embora o rodapé não seja criptografado, a chave é usada para assinar o conteúdo do rodapé, o que significa que novos leitores poderão verificar sua integridade. Os leitores anteriores não são afetados pela adição da assinatura de rodapé.
Exemplos de uso
Os fragmentos de código de amostra a seguir para Python e Scala mostram como criar quadros de dados, gravados em arquivos parquet criptografados, e ler de arquivos parquet criptografados.
-
Python: gravando dados criptografados
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: lendo dados criptografados
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: gravando dados criptografados
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: lendo dados criptografados
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()
Informações internas da manipulação de chave de criptografia
Ao gravar um arquivo Parquet, é gerada uma chave aleatória de criptografia de dados (DEK) para cada coluna criptografada e para o rodapé. Essas chaves são usadas para criptografar os dados e os módulos de metadados no arquivo Parquet.
Em seguida, a chave de criptografia de dados é criptografada com uma chave de criptografia de chaves (KEK), também gerada dentro do Spark/Parquet para cada chave mestra. A chave de criptografia de chaves é criptografada com uma chave mestra de criptografia (MEK), seja localmente, se as chaves mestras forem gerenciadas pelo aplicativo, ou em um serviço KeyProtect, se as chaves mestras forem gerenciadas pelo IBM® Key Protect for IBM Cloud®.
As chaves de criptografia de dados criptografados e as chaves de criptografia de chaves são armazenadas nos metadados do arquivo Parquet, juntamente com a identidade da chave mestra. Cada chave de criptografia de chaves tem uma identidade única (gerada localmente como um valor aleatório de 16 bytes seguro), e também é armazenada nos metadados do arquivo. As chaves de criptografia de chaves são armazenadas em cache pelo token de acesso, portanto, não há necessidade de interagir com o serviço KeyProtect para cada coluna ou arquivo criptografado se eles usarem a mesma chave de criptografia principal.
Ao ler um arquivo Parquet, o identificador da chave mestra de criptografia (MEK), a chave de criptografia de chaves (KEK) criptografada com seu identificador e a chave de criptografia de dados criptografados (DEK) são extraídas dos metadados do arquivo.
A chave de criptografia de chaves é decriptografada com a chave mestra de criptografia, seja localmente, se as chaves mestras forem gerenciadas pelo aplicativo, ou em um serviço KeyProtect, se as chaves mestras forem gerenciadas pelo IBM® Key Protect for IBM Cloud®. As chaves de criptografia de chaves são armazenadas em cache pelo token de acesso, portanto, não há necessidade de interagir com o serviço KeyProtect para cada coluna ou arquivo criptografado se eles usarem a mesma chave de criptografia principal. A chave de criptografia de dados (DEK) é decriptografada localmente, usando a chave de criptografia de chaves (KEK).
Rotação de Chave (recurso opcional)
A prática de criptografia de envelope tem uma opção avançada para girar (mudar) chaves principais para minimizar o risco de vazamento de dados sensíveis devido a MEKs comprometidos. DEKs não podem ser alterados, pois isso significa ter que recriptografar completamente os arquivos de Parquet. Os novos MEKs (e KEKs gerados novamente com transparência) são usados para recriptografar os DEKs.
Para ativar a rotação de chaves em arquivos Parquet, deve-se configurar o parâmetro "parquet.encryption.key.material.store.internally" para "false" na configuração do Hadoop ao gravar os arquivos
do Parquet.
Com esse parâmetro configurado, o Parquet armazena as chaves (envoltas com MEKs) em pequenos arquivos separados em vez de dentro dos arquivos do Parquet. Quando a rotação de chave é executada, apenas os pequenos arquivos de material chave são substituídos. Não há necessidade de modificar os arquivos do Parquet (que muitas vezes são imutáveis). A maioria dos sistemas KMS suporta rotação de chaves substituindo o conteúdo das chaves principais armazenadas e mantendo o ID do MEK intacto (mas atualizando a versão chave). Após um usuário ou administrador ter realizado a rotação de chave principal dentro da instância do KMS usando a API específica do KMS, o mecanismo de rotação de chave do Parquet pode ser acionado (por exemplo, pelo mesmo administrador) chamando:
public static void KeyToolkit.rotateMasterKeys(String folderPath, Configuration hadoopConfig)
Quando a rotação de chave é executada, cada KEK em todos os arquivos de material chave em folderPath é desagrupado com a versão antiga do MEK para ativar a decriptografia do DEK. Um novo KEK é gerado para cada ID de chave principal
e envolto com a nova versão MEK. Criar um novo KEK, em vez de reutilizar o antigo, não significa apenas que a segurança é melhorada, mas também que o desempenho das operações de leitura de dados subsequentes é aumentado. Isso porque um único
processo de rotação de chaves, executado pelo administrador, opera através de vários arquivos criados por diferentes processos, o que significa muitos KEKs diferentes para o mesmo ID do MEK. O processo de rotação de chave substitui os antigos
KEKs por um único novo KEK, o que permite que os leitores executem uma única interação de desagrupamento com KMS para cada chave principal.
Para obter exemplos de como usar rotação de chaves:
- Para gerenciamento de chave por aplicativo, consulte Rotação de chave no gerenciamento de chave por aplicativo.
- Para gerenciamento de chave pelo Key Protect, consulte Gerenciamento de chave de rotação de chave pelo Key Protect.
Saiba mais
Confira o bloco de notas de amostra a seguir para saber como usar a criptografia do Parquet: