AWS Encryption CLIを使ってみた

2018.03.19

はじめに

中山(順)です

今日も他のメンバー書かなそうなネタをお届けしようと思います。

今日はAWS Encryption CLIを紹介したいと思います。 元ネタは以下のブログ記事です。

How to Encrypt and Decrypt Your Data with the AWS Encryption CLI

AWS Encryption CLIとは

AWS Encryption CLIは、ベストプラクティスに基づいて簡単にデータの暗号化・復号を行えるコマンドラインツールです。 AWS Encryption SDK for Pythonを利用して実装されています。

AWS Encryption SDKでは、エンベロープ暗号化により、データと対応するデータキーを保護することができます。

エンベロープ暗号化については、こちらをごらんください。

How the AWS Encryption SDK Works

Concepts in the AWS Encryption SDK

サポートされる暗号化アルゴリズム

サポートされている暗号化スイートの情報は、以下のとおりです。

  • Recommended: AES-GCM with Key Derivation and Signing
  • AES-GCM with Key Derivation Only
  • AES-GCM without Key Derivation or Signing

詳細はこちらのドキュメントを参照してください。

Supported Algorithm Suites in the AWS Encryption SDK

使ってみた

以下のツールがインストールされていることが動作要件となります。

  • python
  • pip
  • AWS CLI

インストール

以下の通り、pipでインストールすることが可能です。

sudo pip install aws-encryption-sdk-cli

インストールしたらバージョンを確認しましょう。

aws-encryption-cli --version
aws-encryption-sdk-cli/1.1.4 aws-encryption-sdk/1.3.3

前準備

ヘルプで使い方を確認してみましょう。

aws-encryption-cli --help
usage: aws-encryption-cli [-h] [--version] [-e] [-d] [-S]
                          [--metadata-output METADATA_OUTPUT]
                          [--overwrite-metadata]
                          [-m MASTER_KEYS [MASTER_KEYS ...]]
                          [--caching CACHING [CACHING ...]] -i INPUT -o OUTPUT
                          [--encode] [--decode]
                          [-c ENCRYPTION_CONTEXT [ENCRYPTION_CONTEXT ...]]
                          [--algorithm {AES_256_GCM_IV12_TAG16,AES_256_GCM_IV12_TAG16_HKDF_SHA256,AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256,AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,AES_128_GCM_IV12_TAG16_HKDF_SHA256,AES_128_GCM_IV12_TAG16,AES_192_GCM_IV12_TAG16,AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,AES_192_GCM_IV12_TAG16_HKDF_SHA256}]
                          [--frame-length FRAME_LENGTH]
                          [--max-length MAX_LENGTH] [--suffix [SUFFIX]]
                          [--interactive] [--no-overwrite] [-r] [-v] [-q]

Encrypt or decrypt data using the AWS Encryption SDK

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -e, --encrypt         Encrypt data
  -d, --decrypt         Decrypt data
  -S, --suppress-metadata
                        Suppress metadata output.
  --metadata-output METADATA_OUTPUT
                        File to which to write metadata records
  --overwrite-metadata  Force metadata output to overwrite contents of file
                        rather than appending to file
  -m MASTER_KEYS [MASTER_KEYS ...], --master-keys MASTER_KEYS [MASTER_KEYS ...]
                        Identifying information for a master key provider and
                        master keys. Each instance must include a master key
                        provider identifier and identifiers for one or more
                        master key supplied by that provider. ex: --master-
                        keys provider=aws-kms key=$AWS_KMS_KEY_ARN
  --caching CACHING [CACHING ...]
                        Configuration options for a caching cryptographic
                        materials manager and local cryptographic materials
                        cache. Must consist of "key=value" pairs. If caching,
                        at least "capacity" and "max_age" must be defined. ex:
                        --caching capacity=10 max_age=100.0
  -i INPUT, --input INPUT
                        Input file or directory for encrypt/decrypt operation,
                        or "-" for stdin.
  -o OUTPUT, --output OUTPUT
                        Output file or directory for encrypt/decrypt
                        operation, or - for stdout.
  --encode              Base64-encode output after processing
  --decode              Base64-decode input before processing
  -c ENCRYPTION_CONTEXT [ENCRYPTION_CONTEXT ...], --encryption-context ENCRYPTION_CONTEXT [ENCRYPTION_CONTEXT ...]
                        key-value pair encryption context values (encryption
                        only). Must a set of "key=value" pairs. ex: -c
                        key1=value1 key2=value2
  --algorithm {AES_256_GCM_IV12_TAG16,AES_256_GCM_IV12_TAG16_HKDF_SHA256,AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256,AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,AES_128_GCM_IV12_TAG16_HKDF_SHA256,AES_128_GCM_IV12_TAG16,AES_192_GCM_IV12_TAG16,AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,AES_192_GCM_IV12_TAG16_HKDF_SHA256}
                        Algorithm name (encryption only)
  --frame-length FRAME_LENGTH
                        Frame length in bytes (encryption only)
  --max-length MAX_LENGTH
                        Maximum frame length (for framed messages) or content
                        length (for non-framed messages) (decryption only)
  --suffix [SUFFIX]     Custom suffix to use when target filename is not
                        specified (empty if specified but no value provided)
  --interactive         Force aws-encryption-cli to prompt you for
                        verification before overwriting existing files
  --no-overwrite        Never overwrite existing files
  -r, -R, --recursive   Allow operation on directories as input
  -v                    Enables logging and sets detail level. Multiple -v
                        options increases verbosity (max: 4).
  -q, --quiet           Suppresses most warning and diagnostic messages

For more usage instructions and examples, see: http://aws-encryption-sdk-
cli.readthedocs.io/en/latest/

マスターキーの作成

マスターキーとしては、AWS KMSのCMK(Customer master key)を利用することができます。 今回は、KMSと連携する前提で操作方法をご紹介していきます。

KEY_DESCRIPTION="CMK for Developers.IO"

aws kms create-key \
    --description "${KEY_DESCRIPTION}"
{
    "KeyMetadata": {
        "Origin": "AWS_KMS",
        "KeyId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "Description": "CMK for Developers.IO",
        "KeyManager": "CUSTOMER",
        "Enabled": true,
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "CreationDate": 1521435985.552,
        "Arn": "arn:aws:kms:ap-northeast-1:XXXXXXXXXXXX:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "AWSAccountId": "XXXXXXXXXXXX"
    }
}

CMKを作成したら、エイリアスを設定しておきましょう。 でないと、マネージメントコンソールでCMKを識別しにくくなります。

KEY_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
ALIAS="alias/EncriptionCLI"

aws kms create-alias \
    --alias-name ${ALIAS} \
    --target-key-id ${KEY_ID}

暗号化するデータの生成

今回は、以下のようなテキストファイルを用意します。

DATA_FILE="plain.txt"

cat << EOF > ${DATA_FILE}
hogehoge
fugafuga
EOF

cat ${DATA_FILE}
hogehoge
fugafuga

暗号化

では暗号化してみます。

sudo aws-encryption-cli \
    --encrypt \
    --input ${DATA_FILE} \
    --master-keys key=${KEY_ID} \
    --output EncryptedMessage \
    --metadata-output ./metadata \
    --encryption-context purpose=test

このうち、以下のオプションについて解説します。

encryption-context

暗号化する際にコンテキストを付与できます。 コンテキストは、"purpose=test"のようにキーとバリューのペアである必要があります。

metadata-output

暗号化した際のコンテキストや使用した暗号化スイートをメタデータとしてファイルに出力できます。

元ネタのブログでは、以下のように記載されています。

The --metadata-output parameter tells the AWS Encryption CLI where to write the metadata for the encrypt command. The metadata includes the full paths to the input and output files, the encryption context, the algorithm suite, and other valuable information that you can use to review the operation and verify that it meets your security standards.

さきほど暗号化した際に出力されたメタデータを確認してみましょう。

cat metadata | jq
{
  "header": {
    "algorithm": "AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384",
    "content_type": 2,
    "encrypted_data_keys": [
      {
        "encrypted_data_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "key_provider": {
          "key_info": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "provider_id": "XXXXXXXXXXXX"
        }
      }
    ],
    "encryption_context": {
      "aws-crypto-public-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "purpose": "test"
    },
    "frame_length": 4096,
    "header_iv_length": 12,
    "message_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "type": 128,
    "version": "1.0"
  },
  "input": "/home/nakayamanobuhiro/encrypted-cli/plain.txt",
  "mode": "encrypt",
  "output": "/home/nakayamanobuhiro/encrypted-cli/EncryptedMessage"
}

復号

復号も同じ要領で行うことが可能です。 metadataについては、デフォルトでは 追記 されます。

aws-encryption-cli \
    --decrypt \
    --input EncryptedMessage \
    --encryption-context purpose=test \
    --metadata-output ./metadata \
    --output DecryptedMessage

結果を確認します。

cat DecryptedMessage
hogehoge
fugafuga

まとめ

このように、AWS Encryption CLI/SDKを使うことで非常に簡単に暗号化/復号を行えます。 あるあるな処理を独自に開発するような車輪の再発明的なことは避けて、できるだけ楽しいことに時間を使っていきたいですね。

この他にも、AWSはAPIを経由して利用するサービスだけでなく、様々なツールやサンプルコードを提供しています。
積極的に活用していきましょう。

Amazon Web Services

Amazon Web Services - Labs

参考情報

Frequently Asked Questions