Crittografia modulare Parquet in Hive - Amazon EMR

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Crittografia modulare Parquet in Hive

La crittografia modulare Parquet fornisce il controllo e la crittografia degli accessi a livello di colonna per migliorare la privacy e l'integrità dei dati archiviati nel formato di file Parquet. Questa funzionalità è disponibile in Amazon EMR Hive a partire dal rilascio 6.6.0.

Le soluzioni di sicurezza e integrità supportate in precedenza, che includono la crittografia dei file o la crittografia del livello di archiviazione, sono descritte in Opzioni di crittografia nella Guida alla gestione di Amazon EMR. Queste soluzioni possono essere utilizzate per i file Parquet, ma sfruttando le nuove funzionalità del meccanismo di crittografia integrato Parquet fornisce un accesso granulare a livello di colonna, oltre a miglioramenti in termini di prestazioni e sicurezza. Scopri di più su questa funzionalità nella pagina github di Apache Crittografia modulare Parquet.

Gli utenti trasmettono le configurazioni a lettori e scrittori Parquet utilizzando configurazioni Hadoop. Le configurazioni dettagliate per consentire agli utenti di configurare lettori e scrittori per abilitare la crittografia e attivare le funzionalità avanzate sono documentate in PARQUET-1854: Properties-driven Interface to Parquet Encryption Management

Esempi di utilizzo

L'esempio seguente illustra la creazione e la scrittura su una tabella Hive che utilizza AWS KMS per la gestione delle chiavi di crittografia.

  1. Implementa a KmsClient per il AWS KMS servizio come descritto nel documento PARQUET-1373: Encryption Key Management Tools. L'esempio seguente mostra un frammento di implementazione.

    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; } }
  2. Crea le chiavi di AWS KMS crittografia per il piè di pagina e le colonne con i ruoli IAM che hanno accesso, come descritto nella sezione Creazione di chiavi nella Developer Guide.AWS Key Management Service Il ruolo IAM predefinito è EMR_ECS_default.

  3. Nell'applicazione Hive su un cluster Amazon EMR, aggiungi il client precedente utilizzando l'istruzione ADD JAR, come descritto in Risorse Apache Hive. Di seguito è mostrato un esempio di istruzione della policy:

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

    Un metodo alternativo consiste nell'aggiungere il JAR ad auxlib of Hive utilizzando un'azione bootstrap. Di seguito è riportato un esempio di riga da aggiungere all'azione boostrap:

    aws s3 cp 's3://location-to-custom-jar' /usr/lib/hive/auxlib
  4. Imposta le seguenti configurazioni:

    set parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory; set parquet.encryption.kms.client.class=org.apache.parquet.crypto.keytools.AwsKmsClient;
  5. Crea una tabella Hive in formato Parquet e specifica le AWS KMS chiavi in SERDEPROPERTIES e inserisci alcuni dati al suo interno:

    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;
  6. Verifica che quando crei una tabella esterna nella stessa posizione senza accesso alle AWS KMS chiavi (ad esempio, accesso al ruolo IAM negato), non puoi leggere i dati.

    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;
  7. L'ultima istruzione dovrebbe generare la seguente eccezione:

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