

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Criptografia modular em Parquet no Hive
<a name="hive-parquet-modular-encryption"></a>

A criptografia modular em Parquet fornece controle de acesso e criptografia em nível colunar para aprimorar a privacidade e a integridade dos dados armazenados no formato de arquivo Parquet. Esse atributo está disponível no Hive no Amazon EMR desde a versão 6.6.0.

As soluções anteriormente compatíveis para segurança e integridade, que incluem a criptografia de arquivos ou a criptografia da camada de armazenamento, estão descritas em [Opções de criptografia](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-data-encryption-options.html) no Guia de gerenciamento do Amazon EMR. Essas soluções podem ser usadas para arquivos Parquet, mas o uso dos novos atributos do mecanismo de criptografia integrado do Parquet fornece acesso granular ao nível de coluna, além de melhorias na performance e na segurança. Saiba mais sobre esse atributo na página do Apache no github [Criptografia modular em Parquet](https://github.com/apache/parquet-format/blob/master/Encryption.md).

Os usuários transmitem configurações para leitores e gravadores do Parquet usando as configurações do Hadoop. As configurações detalhadas para que os usuários configurem leitores e gravadores para habilitar a criptografia e também alternar atributos avançados estão documentadas em [PARQUET-1854: interface orientada por propriedades para o gerenciamento de criptografia em Parquet](https://docs.google.com/document/d/1boH6HPkG0ZhgxcaRkGk3QpZ8X_J91uXZwVGwYN45St4/edit) 

## Exemplos de uso
<a name="usage-examples"></a>

O exemplo a seguir aborda a criação e gravação em uma tabela do Hive usando AWS KMS para gerenciar chaves de criptografia.

1. Implemente um KmsClient para o AWS KMS serviço conforme descrito no documento [PARQUET-1373: Ferramentas de gerenciamento de chaves de criptografia](https://docs.google.com/document/d/1bEu903840yb95k9q2X-BlsYKuXoygE4VnMDl9xz_zhk/edit). O exemplo a seguir mostra um trecho de implementação.

   ```
   package org.apache.parquet.crypto.keytools;
   
   import com.amazonaws.AmazonClientException;
   import com.amazonaws.AmazonServiceException;
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.kms.AWSKMS;
   import com.amazonaws.services.kms.AWSKMSClientBuilder;
   import com.amazonaws.services.kms.model.DecryptRequest;
   import com.amazonaws.services.kms.model.EncryptRequest;
   import com.amazonaws.util.Base64;
   import org.apache.hadoop.conf.Configuration;
   import org.apache.parquet.crypto.KeyAccessDeniedException;
   import org.apache.parquet.crypto.ParquetCryptoRuntimeException;
   import org.apache.parquet.crypto.keytools.KmsClient;
   import org.slf4j.Logger;
   import org.slf4j.LoggerFactory;
   
   import java.nio.ByteBuffer;
   import java.nio.charset.Charset;
   import java.nio.charset.StandardCharsets;
   
   public class AwsKmsClient implements KmsClient {
   
       private static final AWSKMS AWSKMS_CLIENT = AWSKMSClientBuilder
               .standard()
               .withRegion(Regions.US_WEST_2)
               .build();
       public static final Logger LOG = LoggerFactory.getLogger(AwsKmsClient.class);
   
       private String kmsToken;
       private Configuration hadoopConfiguration;
   
       @Override
       public void initialize(Configuration configuration, String kmsInstanceID, String kmsInstanceURL, String accessToken) throws KeyAccessDeniedException {
           hadoopConfiguration = configuration;
           kmsToken = accessToken;
   
       }
   
       @Override
       public String wrapKey(byte[] keyBytes, String masterKeyIdentifier) throws KeyAccessDeniedException {
           String value = null;
           try {
               ByteBuffer plaintext = ByteBuffer.wrap(keyBytes);
   
               EncryptRequest req = new EncryptRequest().withKeyId(masterKeyIdentifier).withPlaintext(plaintext);
               ByteBuffer ciphertext = AWSKMS_CLIENT.encrypt(req).getCiphertextBlob();
   
               byte[] base64EncodedValue = Base64.encode(ciphertext.array());
               value = new String(base64EncodedValue, Charset.forName("UTF-8"));
           } catch (AmazonClientException ae) {
               throw new KeyAccessDeniedException(ae.getMessage());
           }
           return value;
       }
   
       @Override
       public byte[] unwrapKey(String wrappedKey, String masterKeyIdentifier) throws KeyAccessDeniedException {
           byte[] arr = null;
           try {
               ByteBuffer ciphertext  = ByteBuffer.wrap(Base64.decode(wrappedKey.getBytes(StandardCharsets.UTF_8)));
               DecryptRequest request = new DecryptRequest().withKeyId(masterKeyIdentifier).withCiphertextBlob(ciphertext);
               ByteBuffer decipheredtext = AWSKMS_CLIENT.decrypt(request).getPlaintext();
               arr = new byte[decipheredtext.remaining()];
               decipheredtext.get(arr);
           } catch (AmazonClientException ae) {
               throw new KeyAccessDeniedException(ae.getMessage());
           }
           return arr;
       }
   }
   ```

1. Crie suas chaves de AWS KMS criptografia para o rodapé e para as colunas com suas funções do IAM tendo acesso conforme descrito em [Criação de chaves](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html) no *Guia do AWS Key Management Service desenvolvedor*. O perfil do IAM padrão é EMR\$1ECS\$1default.

1. Na aplicação do Hive em um cluster do Amazon EMR, adicione o cliente acima usando a instrução `ADD JAR`, conforme descrito na [documentação de recursos do Apache Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Cli#LanguageManualCli-HiveResources). Este é um exemplo de instrução:

   ```
   ADD JAR 's3://location-to-custom-jar';
   ```

   Um método alternativo é adicionar o JAR ao `auxlib` do Hive usando uma ação de bootstrap. Veja a seguir um exemplo de linha a ser adicionada à ação de boostrap:

   ```
   aws s3 cp 's3://location-to-custom-jar' /usr/lib/hive/auxlib 
   ```

1. Defina as seguintes configurações:

   ```
   set parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory;
   set parquet.encryption.kms.client.class=org.apache.parquet.crypto.keytools.AwsKmsClient;
   ```

1. Crie uma tabela do Hive com formato Parquet e especifique as AWS KMS chaves em SERDEPROPERTIES e insira alguns dados nela:

   ```
   CREATE TABLE my_table(name STRING, credit_card STRING)
   ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe’
   WITH SERDEPROPERTIES (
     'parquet.encryption.column.key’=<aws-kms-key-id-for-column-1>: credit_card’,
     'parquet.encryption.footer.key’='<aws-kms-key-id-for-footer>’)
   STORED AS parquet
   LOCATION “s3://<bucket/<warehouse-location>/my_table”;
   
   INSERT INTO my_table SELECT 
   java_method ('org.apache.commons.lang.RandomStringUtils','randomAlphabetic',5) as name,
   java_method ('org.apache.commons.lang.RandomStringUtils','randomAlphabetic',10) as credit_card
   from (select 1) x lateral view posexplode(split(space(100),' ')) pe as i,x;
   
   select * from my_table;
   ```

1. Verifique se, ao criar uma tabela externa no mesmo local sem acesso às AWS KMS chaves (por exemplo, acesso negado à função do IAM), você não consegue ler os dados.

   ```
   CREATE EXTERNAL TABLE ext_table (name STRING, credit_card STRING)
   ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe’
   STORED AS parquet
   LOCATION “s3://<bucket>/<warehouse-location>/my_table”;
   
   SELECT * FROM ext_table;
   ```

1. A última instrução deve gerar a seguinte exceção:

   ```
   Failed with exception java.io.IOException:org.apache.parquet.crypto.KeyAccessDeniedException: Footer key: access denied
   ```