暗号鍵の使用

概要

デフォルトでは、Cloud Storage は、Google 管理の暗号鍵と AES256 暗号化アルゴリズムを使用して、すべてのオブジェクト データを暗号化します。ただし、顧客指定の暗号鍵(CSEK)または Google Cloud KMS で管理する顧客管理の暗号鍵(CMEK)のいずれかの暗号鍵タイプを使用することもできます。Cloud Storage では、CSEK を Google のサーバーに永続的に保存したり、管理したりすることはありません。こうした暗号化オプションの詳細については、CMEKCSEK をご覧ください。

gsutil は、JSON API を使用して Cloud Storage オブジェクトを操作するための CSEK を受け入れます。これらの鍵は、次のように .boto 構成ファイルで指定します。

[GSUtil]
encryption_key = ...
decryption_key1 = ...
decryption_key2 = ...

各鍵は、RFC 4648 Base64 でエンコードされた 256 ビットの文字列で、AES256 暗号化アルゴリズムで使用されます。

gsutil は、JSON API を使用してオブジェクトを暗号化するための CMEK も受け入れます。バケット内の新しく書き込まれたすべてのオブジェクトを暗号化することが目的である場合は、そのバケットのデフォルトの KMS 鍵を設定する必要があります(gsutil help kms を参照)。 また、.boto 構成ファイルで必要な CMEK を指定することもできます。その場合は encryption_key 属性を指定するだけで済みます。

[GSUtil]
encryption_key = projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEYNAME

CSEK で暗号化されたオブジェクトの復号には、decryption_key 属性のいずれかで CSEK を指定する必要がありますが、オブジェクトの暗号化に使用された CMEK の名前はオブジェクトのメタデータに保存されるため、CMEK で暗号化されたオブジェクトの復号には不要です。

boto ファイルを編集する必要なしにコマンドごとに CMEK を指定する場合は、鍵の名前を最上位の boto オプションとして指定できます。

gsutil -o 'GSUtil:encryption_key=projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEYNAME' \
       cp /some/local/file gs://my-bucket/

暗号化の動作

.boto 構成ファイルには、1 つの encryption_key と複数の decryption_keys を指定できます。

.boto 構成ファイル内に encryption_key が存在する場合、gsutil では Cloud Storage に書き込まれたデータまたはコピーされたデータがその鍵で暗号化されます。 encryption_key が指定されていない場合、gsutil では書き込みまたはコピーするすべてのデータに宛先バケットのデフォルトの暗号化タイプを使用します。バケットにデフォルトの KMS 鍵セットがある場合は、その CMEK が暗号化に使用されます。ない場合は、Google が管理する暗号化が使用されます。

CSEK で暗号化されたオブジェクトは、gsutil cat、cp、mv、rsync コマンドでダウンロードまたはコピーされるときに、対応する復号鍵を必要とします。ls -L または stat コマンドで、このようなオブジェクトの CRC32C または MD5 ハッシュを表示する場合にも対応する復号キーが必要になります。

一致する鍵が .boto 構成に存在している場合、gsutil では必要に応じて Cloud Storage へのリクエストでこの鍵を提供し、復号された結果を処理します。gsutil では、暗号化されたデータをローカル ディスクに保存しません。

gsutil では、鍵の SHA256 ハッシュと CSEK のハッシュを比較することで、クラウド オブジェクトに使用する正しい CSEK が自動的に検出されます。gsutil では、一致の検索時に、構成済みの暗号鍵と最大 100 個の復号鍵が考慮されます。boto 構成ファイルで、復号鍵は昇順に並んでいる必要があります。また、先頭の鍵の番号は 1 でなければなりません。たとえば、次のような構成の場合について考えてみます。

decryption_key1 = ...
decryption_key9 = ...
decryption_key10 = ...
decryption_key11 = ...

decryption_keys 2 から 8 までの値が設定されていないので、decryption_keys 9、10、11 は無視されます。

再開可能な操作と暗号鍵

書き込み操作やコピー操作が完了する前に boto 構成ファイルの暗号鍵が変更されると(たとえば、^C を押したか、ネットワーク タイムアウトが発生した後で gsutil cp を再実行してオブジェクトをアップロードした場合)、gsutil は、部分的に完了している操作を再開し、宛先オブジェクトを新しいキーで書き込みます。

顧客指定の暗号鍵の生成

暗号鍵に使用する 256 ビットの RFC 4648 Base64 エンコード文字列は、Python で簡単に生成できます。

python -c 'import base64; import os;\
           print(base64.encodestring(os.urandom(32)))'

顧客指定の暗号鍵の管理

Google では CSEK を保存しないため、CSEK を紛失すると、その鍵で暗号化されたすべてのデータに完全にアクセスできなくなります。 このため、暗号鍵のバックアップを安全な場所に作成することをおすすめします。.boto 構成ファイル以外の場所にも鍵を保存しておく必要があります。

また、CSEK の作成時に、鍵とオブジェクトへのアクセス権を持つすべてのユーザーがオブジェクトのデータを読み取ることが可能です。暗号鍵を信頼できない第三者と共有しないように、対策を講じる必要があります。

鍵のローテーション

CSEK をローテーションするには、encryption_key 構成値を復号鍵の構成値に変更し、encryption_key に新しい値を使用します。次に、rewrite コマンドを実行してクラウドでキーのローテーションを行います。このとき、データのダウンロードとアップロードは行いません。たとえば、最初の設定が次のようになっているとします。

# Old encryption key
encryption_key = keyA...

この設定を次のように変更します。

# New encryption key
encryption_key = keyB...
# Encryption key prior to rotation
decryption_key1 = keyA...

次のコマンドを実行して、オブジェクトの暗号鍵のローテーションを行います。

gsutil rewrite -k gs://bucket/object temp-file

これを別の CMEK に適用することもできますが、復号鍵の構成値に CMEK を追加する必要はありません。同様に、encryption_key 構成値で指定された鍵のタイプに応じて、CSEK と CMEK の暗号化を切り替えることが可能です。

暗号鍵のパフォーマンスへの影響

オブジェクトの一覧表示を実行するとき、CSEK または CMEK で暗号化されたオブジェクトのメタデータにオブジェクトの CRC32C または MD5 ハッシュは含まれません。gsutil コマンドでこれらのフィールドが必要な場合(gsutil ls -L など)では、gsutil では CSEK または CMEK で暗号化されたオブジェクトごとに追加のメタデータ GET リクエストを実行します。 このようなオブジェクトの一覧を -L フラグで取得すると、オブジェクトごとに 1 回の追加操作が必要になるため、Google 所有のキーで暗号化されたオブジェクトの一覧表示よりも処理が大幅に遅くなります。

顧客指定の暗号鍵を使用する場合のセキュリティ

gsutil は常に HTTPS で暗号鍵を送信するため、CSEK がネットワーク上で露出することはありません。こうした鍵は、.boto 構成ファイルだけでなく、gsutil を実行するマシンのメモリ上にも存在します。このファイルやマシンのセキュリティが侵害された場合、暗号鍵も侵害されたものと考え、このキーで暗号化されたすべてのオブジェクトで鍵のローテーションをすぐに実行する必要があります。

サポートされていない XML API

gsutil では、XML API を使用して暗号化されたオブジェクトを操作できません。encryption_key または decryption_keys を構成で指定している場合には、JSON API を使用します。