Amazon S3 の暗号化されたデータファイルを Amazon Redshift にロードする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

データ分析で用いられるデータファイルは、大容量かつ機密情報を含むことが多くありますので、万が一の情報漏洩のリスクを考慮して、S3に置く際に暗号化が要件とされることがあります。今回は、Amazon S3 の暗号化されたデータファイルを Amazon Redshift にロードする方法をいくつかご紹介します。

Amazon S3 のファイルの暗号化のおさらい

S3暗号化方式の種類

Amazon S3 のファイルの暗号化は、クライアントサイドが1種類、サーバーサイドが3種類あります。

  1. お客様が用意したキーによるクライアントサイドの暗号化 (CSE)
  2. Amazon S3 で管理されたキーによるサーバーサイドの暗号化 (SSE-S3)
  3. お客様が用意したキーによるサーバーサイドの暗号化 (SSE-C)
  4. AWS KMS で管理されたキーによるサーバーサイドの暗号化 (SSE-KMS)

S3の暗号化については、Amazon S3暗号化と運用サーバー側の暗号化を使用したデータの保護をご覧ください。

Amazon Redshift でサポートしている暗号化されたデータファイルは、1と2です。さらに1と2を組み合わせた暗号化もサポートしています。

お客様が用意したキーによるクライアントサイドの暗号化 (CSE)とは

クライアントサイドの暗号化(Client Side Encryption(以降、CSEと略す))はお客様が用意したキーによって、クライアント内で暗号化したオブジェクトをS3に登録しますので、暗号化されたオブジェクトはユーザー以外に復号化が不可能です。

  • クライアント内で暗合したオブジェクトをS3に登録
  • 暗号化されたオブジェクトはユーザー以外に複合化が不可能
  • AWS SDK(Java、Ruby、PHP、.NET)のクライアントサイドの機能として暗号化機能を提供

cse-flow

Amazon S3 で管理されたキーによるサーバーサイドの暗号化 (SSE-S3)とは

サーバーサイドの暗号化(Server Side Encryption with Amazon S3-Managed Keys(以降、SSE-S3と略す))は、クライアントから暗号化オプションを指定して登録するだけで、サーバー内で鍵が自動生成され、暗号化したデータを保存します。鍵はユーザーが管理する必要がなく、AWSで管理されるので手間をかけずに暗号化できます。

  • クライアントから暗号化オプションを指定して登録する
  • サーバー内で鍵が自動生成され、暗号化したデータを保存する
  • 鍵はユーザーが管理する必要がなく、AWSで管理されるので手間をかけずに暗号化できる
  • AWS SDKやAWS CLIから利用できる

sse-flow

CSE で暗号化されたファイルをロードする方法

手順

  1. Java のポリシーファイルを書き換え
  2. 暗号化ファイルの作成
  3. CSE で暗号化したファイルをS3にアップロード
  4. S3 から Redshift にロードする

手順1〜3については、S3のユーザ提供キーによるクライアントサイド暗号化 (CSE) を使い倒す の手順に従い、ファイルをアップロードしてください。

4. S3 から Redshift にロードする

ロードするテーブルは、以下と通りです。

CREATE TABLE users (
  id int,
  name varchar(32),
  created timestamp
);

以下のCOPY文を実行して、CSE暗号化したデータファイルをテーブルにロードします。CSEでは、CREDENTIALS に master_symmetric_key を追加指定します。master_symmetric_key にはアップロードの時に使用した秘密鍵をBase64エンコードした文字列です。例えば、”wsQfcvH2s7NVEpl8gVlOtiSfzK1wXMYwMJI3t8/4bsE=” のような文字列です。

COPY users
FROM 's3://cm-bucket/users.csv'
CREDENTIALS 'aws_access_key_id=<access_key_id>;aws_secret_access_key=<secret_access_key>;master_symmetric_key=<Base64エンコードした秘密鍵>'
TIMEFROMAT 'auto'
DELIMITER ','
ENCRYPTED;

SSE-S3 で暗号化されたファイルをロードする方法

手順

  1. SSE-S3 でファイルをS3にアップロード
  2. S3 から Redshift にロードする

1. SSE-S3 でファイルをS3にアップロード

クライアントから暗号化オプションを指定して登録するだけで、サーバー内で鍵が自動生成され、暗号化したデータを保存します。以下、AWSCLIを利用してSSE-S3によるファイルのアップロードしてみます。"--sse"オプションを付けることで SSE-S3 で暗号化されます。

aws s3 cp users.csv s3://cm-bucket/users.csv --sse

2. S3 から Redshift にロードする

ロードするテーブルは、以下と通りです。

CREATE TABLE users (
  id int,
  name varchar(32),
  created timestamp
);

以下のCOPY文を実行して、SSE-S3暗号化したデータファイルをテーブルにロードします。SSE-S3では、暗号化の指定は一切不要です。S3からファイルを取得した時に復号化され、Redshiftにロードされます。

COPY users
FROM 's3://cm-bucket/users.csv'
CREDENTIALS 'aws_access_key_id=<access_key_id>;aws_secret_access_key=<secret_access_key>'
TIMEFORMAT 'auto'
DELIMITER ',' ;

CSE と SSE-S3 で暗号化されたファイルをロードする方法

手順

  1. Java のポリシーファイルを書き換え
  2. 暗号化ファイルの作成
  3. CSE で暗号化したファイルをS3にアップロード
  4. S3 から Redshift にロードする

手順1〜2については、S3のユーザ提供キーによるクライアントサイド暗号化 (CSE) を使い倒す  の手順に従い、ファイルをアップロードしてください。

3. CSE と SSE-S3 の2重に暗号化したファイルをS3にアップロード

データファイルを暗号化して、S3バケットにファイルを保存します。CSE暗号化は AWS SDK for Java が暗号化します。秘密鍵を指定して AmazonS3EncryptionClient のインスタンスでファイルを S3 にアップロードします。また、SSE-S3暗号化はアップロードするときのオプションを指定することで、S3に格納されるときに更にSSE-S3暗号化されます。

以下のサンプルコードの「秘密鍵ファイルのパス」「バケット名」「キー名」「アップロードするファイルパス」を環境に合わせて書き換えてください。

    /** 秘密鍵ファイルのパス */
    private static final String symmetricKeyPath = "<秘密鍵のファイルパス>";

    /** バケット名(ex. cm-bucket) */
    private static final String bucketName = "<バケット名>";
    /** キー名(ex. users.csv) */
    private static final String key = "<ファイル名もしくはファイルパス>";

    /** アップロードするファイルパス */
    private static final String uploadPath = "<アップロードするファイルパス>";

    public static void main(String[] args) {
        try {
            // オブジェクトの生成
            S3ClientSideEncryption s3cse = new S3ClientSideEncryption(symmetricKeyPath);
            System.out.println("master_symmetric_key: " + s3cse.getSymmetricKeyBase64());

            // ファイルのS3アップロード
            File uploadFile = new File(uploadPath);
            if (uploadFile.exists()) {
                s3cse.setSSES3Enabled(true);
                PutObjectResult result = s3cse.putFile(bucketName, key, uploadFile);
                if (result == null) {
                    System.err.println("Upload failed.");
                } else {
                    System.out.println("Upload success.");
                }
            } else {
                System.err.println("File not found.:" + uploadPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

4. S3 から Redshift にロードする

ロードするテーブルは、以下と通りです。

CREATE TABLE users (
  id int,
  name varchar(32),
  created timestamp
);

以下のCOPY文を実行して、CSE と SSE-S3 で暗号化されたデータファイルをテーブルにロードします。実行するCOPY文はCSE で暗号化されたデータファイルをロードした場合と変わりません。

COPY users
FROM 's3://cm-bucket/users.csv'
CREDENTIALS 'aws_access_key_id=<access_key_id>;aws_secret_access_key=<secret_access_key>;master_symmetric_key=<Base64エンコードした秘密鍵>'
TIMEFROMAT 'auto'
DELIMITER ','
ENCRYPTED;

最後に

CSE、SSE-S3、CSE+SSE-S3 による暗号化ファイルのアップロードと、それら暗号化ファイルのRedshiftにロードする方法をご紹介しました。CSEの方法さえわかっていれば、こんなにカジュアルに暗号化、そして暗号化ファイルのデータロードが可能です。