AWS Encryption CLI v2 を使ってみた

暗号化をするためのコマンド aws-encryption-cli が v2 になって大幅に使い勝手が変わっているので、基本的な使い方をまとめました
2021.03.28

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

AWS Encryption CLI v2 を使ってみた

v1 の記事はこちら。

AWS Encryption CLIを使ってみた

必須のオプション名が変わっているため、新しく記事を書きました。

AWS Encryption CLI とは何か ?

AWS から提供されているデータ暗号化用のコマンドラインインターフェイスです。

https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/crypto-cli.html

2021 年 3 月現在、まだドキュメントが日本語訳されていないようです。

Python で記述されており、 AWS KMS だけでなく、独自のマスターキーを用いた暗号化をサポートしています。

事前に AWS KMS についての知識があると暗号化も捗ります。参考記事はこちら。

10分でわかる!Key Management Serviceの仕組み #cmdevio

本記事では AWS KMS を使った暗号化を試してみます。

インストール

公式ドキュメントに沿ってインストールしましょう。

AWS KMS を使う場合は AWC CLI のインストールが必要です。本記事を見ながら試したい場合はインストールしてください。プロファイルの設定も忘れずに。

また、 AWS Encryption CLI では Python 3.4 以上、 AWS CLI では Python 3.7 以上を求められますので、事前に Python 3.7 をインストールしましょう。言語のバージョン管理ツールは anyenv がオススメです。

また、コマンドの出力結果が JSON なので jq コマンドもインストールしてあると作業しやすいです。

マスターキーの作成

検証用に適当なマスターキーを作成しましょう。オペレーションミスを防ぐため、他で使っているマスターキーを流用するのは避けてください。

AWS コンソールから作成するか、次のようなコマンドで発行します。ここでは experiments プロファイルを用いています。

aws \
    --profile experiments \
    kms \
    create-key \
    --description sample

成功すると次のような結果が表示されます。AWSAccountId はお使いの AWS アカウントの ID 、 KeyId はあなたが生成したマスターキーの ID で表示されるはずです。

{
    "KeyMetadata": {
        "AWSAccountId": "xxxxyyyyzzzz",
        "KeyId": "89c464cf-7407-4c16-a1a8-8c3cf7b57c03",
        "Arn": "arn:aws:kms:ap-northeast-1:xxxxyyyyzzzz:key/89c464cf-7407-4c16-a1a8-8c3cf7b57c03",
        "CreationDate": "2021-03-23T18:18:40.188000+09:00",
        "Enabled": true,
        "Description": "sample",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER",
        "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
        "EncryptionAlgorithms": [
            "SYMMETRIC_DEFAULT"
        ]
    }
}

マスターキーは基本的にキー ID で識別するのですが、 32 桁の英数字ではつらいのでわかりやすい名前をつけられます。これをエイリアスと言います。

エイリアスを作成するために次のコマンドを使用します。 --target-key-id は先ほど作成したマスターキーのキー ID を指定してください。 --alias-namealias という文字列ではじまる必要があることに注意してください。

aws \
    --profile experiments \
    kms \
    create-alias \
    --alias-name "alias/encryption-sample" \
    --target-key-id "89c464cf-7407-4c16-a1a8-8c3cf7b57c03"

このコマンドは成功すると何も出力しません。うまくできたかわからないので、 AWS コンソールから確認するか、次のコマンドでエイリアスの一覧を出力して作成がうまくいったかを確かめましょう。

2021 年 3 月現在、 AWS コンソールでは次のように表示されます。

AWS コンソールでのエイリアスの見え方

暗号化

さていよいよ暗号化です。まずは暗号化したいデータを用意しましょう。適当に JSON ファイルを用意します。

{
  "id": "januswel",
  "password": "this is a secret, isn't this?"
}

暗号化は次のようにコマンドを叩いてください。

aws-encryption-cli \
    --encrypt \
    --input ./secret.json \
    --output encrypted \
    --encode \
    --metadata-output ./metadata.encrypted \
    --wrapping-keys key=arn:aws:kms:ap-northeast-1:xxxxyyyyzzzz:alias/sample profile=experiments \
    --encryption-context purpose=sample

--input へ暗号化したいデータが格納されたファイルの名前を指定してください。 - を指定することで標準入力から読み込んだデータを暗号化することも可能なようです。

--output で暗号化したデータを格納するファイル名を指定します。 --encode は Base64 エンコードした形で出力するためのオプションです。暗号化したデータをネットワーク通信に載せる場合などに役立つでしょう。

--metadata-output には暗号化に使用した様々なデータを記録するファイルの名前を指定します。暗号化成功後に開いてみてください。データキーやマスターキーなどが暗号化されてこのファイルに格納されています。 JSON なので見づらい場合は jq で整形すると良いでしょう。

cat ./metadata.encrypted | jq .

v1 では --master-keys で指定していたマスターキーですが、 v2 では --wrapping-keys で指定することになっています。複数のマスターキーを指定することも可能で、 1 つめがデータキーの生成に使用され、 2 つめ以降がデータキーの暗号化に使用されます。 1 つだけ指定した場合は生成と暗号化ともに指定したもので実行されます。プロファイル名の指定などはこのオプションで指定します。 profile= に続けてプロファイル名を書きましょう。

--encryption-context は合言葉のようなものです。復号する際にも同様の値を指定する必要があります。実際に運用する場合は複数指定しましょう。

復号

暗号化したものを復号して、元のデータが得られることを確認してみましょう。

aws-encryption-cli \
    --decrypt \
    --input ./encrypted \
    --decode \
    --output decrypted \
    --metadata-output ./metadata.decrypted \
    --wrapping-keys key=arn:aws:kms:ap-northeast-1:xxxxyyyyzzzz:key/0a89eb69-2e35-442f-b720-7aafae5f0a25 profile=experiments \
    --encryption-context purpose=sample

特に解説しないオプションは暗号化時と同じ用途と考えてください。

--decode を指定すると復号前に Base64 デコードしてくれます。暗号化時に --encode している場合は対となります。

--wrapping-keys で指定しているマスターキーがキー ARN であることに注意してください。復号時にキー ID やエイリアスを使用することはできません。

To specify an AWS KMS wrapping key in a decrypt command, the value of the key attribute must be a key ARN. If you use a key ID, alias name, or alias ARN, the wrapping key isn't recognized.

さて、復号できたら元のデータと同じかどうかをみてみましょう。次のコマンドを叩いて、何も表示されなければ成功です。

diff -u secret.json decrypted

備考

暗号化は理解すべきことが多く、使用に際して最新の注意が必要な分、大変だと思ってしまう方も多いと思います。

そんな方でも安全に暗号化を使えるよう、 AWS はベストプラクティスも提供してくれています。

https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/best-practices.html

各項目をチェックリストとして使用することも可能です。ぜひ役立ててください。