Hive の寄木細工モジュラー暗号化 - Amazon EMR

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Hive の寄木細工モジュラー暗号化

Parquet モジュラー暗号化は、列指向レベルのアクセス制御と暗号化を提供し、Parquet ファイル形式で保存されたデータのプライバシーとデータ整合性を強化します。この機能は、リリース 6.6.0 以降の Amazon EMR Hive で使用できます。

ファイルの暗号化やストレージレイヤーの暗号化など、以前にサポートされていたセキュリティと整合性のためのソリューションについては、Amazon EMR 管理ガイドの「暗号化オプション」で説明されています。これらのソリューションはParquetファイルにも使用できますが、統合されたParquet暗号化メカニズムの新機能を活用することで、列レベルへのきめ細かなアクセスが可能になり、パフォーマンスとセキュリティも向上します。この機能の詳細については、Apache github ページ「寄木細工のモジュラー暗号化」を参照してください。

ユーザーは Hadoop 構成を使用して Parquet リーダーとライターに構成を渡します。ユーザーがリーダーとライターを設定して暗号化を有効にしたり、高度な機能を切り替えたりするための詳細な構成については、「PARQUET-1854: Parquet暗号化管理のプロパティ駆動型インターフェイス」を参照してください。

使用例

次の例では、AWS KMS暗号化キーの管理に使用する Hive テーブルの作成と書き込みについて説明します。

  1. ドキュメント「PARQUET-1373: 暗号化キー管理ツール」で説明されているように、 KmsClient AWS KMSサービス用にを実装します。次の例は、実装スニペットを示しています。

    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. AWS Key Management Service開発者ガイドの「キーの作成」の説明に従って、IAMAWS KMS ロールにアクセス権限を持つフッターと列の暗号化キーを作成します。デフォルトの IAM ロールは EMR_ECS_Default です。

  3. Amazon EMR クラスター上の Hive アプリケーションで、Apache Hive リソースのドキュメントで説明されているようにADD JARステートメントを使用して上記のクライアントを追加します。ステートメントの例を以下に示します。

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

    別の方法として、ブートストラップアクションを使用して JAR をauxlib Hive に追加する方法があります。ブートストラップアクションに追加する行の例を以下に示します。

    aws s3 cp 's3://location-to-custom-jar' /usr/lib/hive/auxlib
  4. 次の構成を設定します。

    set parquet.crypto.factory.class=org.apache.parquet.crypto.keytools.PropertiesDrivenCryptoFactory; set parquet.encryption.kms.client.class=org.apache.parquet.crypto.keytools.AwsKmsClient;
  5. Parquet 形式の Hive テーブルを作成し、SERDEPROPERTIESAWS KMS でキーを指定し、そこにデータを挿入します。

    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. AWS KMSキーにアクセスできない外部テーブルを同じ場所に作成すると (IAM ロールのアクセスが拒否された場合など)、データを読み取れないことを確認します。

    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. 最後のステートメントでは、次の例外が発生するはずです。

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