Help us understand the problem. What is going on with this article?

[JAWS-UG CLI] Amazon KMS 入門 (2) データの暗号化・復号化

More than 3 years have passed since last update.

このハンズオンについて

この手順は、JAWS-UG CLI専門支部 #58 KMS入門で実施したものです。

前提条件

必要な権限

作業にあたっては、以下の権限を有したIAMユーザもしくはIAMロールを利用してください。

  • KMSに対するフルコントロール権限
  • S3に関するフルコントロール権限
  • STSに関するフルコントロール権限
  • IAMに関するフルコントロール権限

0. 準備

0.1. リージョンを指定

コマンド
export AWS_DEFAULT_REGION='ap-northeast-1'

0.2. 資格情報を確認

コマンド
aws configure list

インスタンスプロファイルを設定したEC2インスタンスでアクセスキーを設定せずに実行した場合、以下のようになります。

結果
Name                    Value             Type    Location
----                    -----             ----    --------
profile                <not set>             None    None
access_key     ****************RDPA         iam-role
secret_key     ****************9GA8         iam-role
region           ap-northeast-1              env    AWS_DEFAULT_REGION

0.3. バージョン確認

コマンド
aws --version
結果
aws-cli/1.10.56 Python/2.7.10 Linux/4.4.15-25.57.amzn1.x86_64 botocore/1.4.46

0.4. バージョンアップ(必要に応じて)

コマンド
sudo pip install -U awscli

0.5. 変数の設定

この手順の前に定義しておくべき変数を設定します。

コマンド
USER_NAME='jawsug-cli-user'

ALIAS="alias/cli-handson0815"

KEY_ID=$(aws kms list-aliases \
    --query "Aliases[?AliasName == \`${ALIAS}\`].TargetKeyId" \
    --output text) \
    && echo ${KEY_ID}

1. 利用者情報の認証情報取得

一般ユーザの認証情報を生成し、プロファイルとして設定します。

1.1. access keyの作成と取得

変数の確認

コマンド
cat << ETX

    USER_NAME: ${USER_NAME}

ETX
結果
    USER_NAME: jawsug-cli-user

access keyの作成と取得

コマンド
aws iam create-access-key \
    --user-name ${USER_NAME} \
    > ${USER_NAME}.json \
    && cat ${USER_NAME}.json
結果
{
    "AccessKey": {
        "UserName": "jawsug-cli-user",
        "Status": "Active",
        "CreateDate": "2016-08-06T05:55:49.222Z",
        "SecretAccessKey": "****************************************",
        "AccessKeyId": "********************"
    }
}

アクセスキーの抽出

コマンド
USER_ACCESS_KEY=$( \
    cat ${USER_NAME}.json \
    | jp.py 'AccessKey.AccessKeyId' \
    | sed 's/"//g') \
    && echo ${USER_ACCESS_KEY}

USER_SECRET_ACCESS_KEY=$( \
    cat ${USER_NAME}.json \
    | jp.py 'AccessKey.SecretAccessKey' \
    | sed 's/"//g') \
    && echo ${USER_SECRET_ACCESS_KEY}

1.2. プロファイル名の指定

コマンド
USERS_PROFILE_NAME=${USER_NAME}

1.3. プロファイルの確認

プロファイル名が未使用であることを確認します。

コマンド
aws configure get aws_access_key_id \
    --profile ${USERS_PROFILE_NAME}
結果
The config profile (jawsug-cli-user) could not be found
コマンド
aws configure get aws_secret_access_key \
    --profile ${USERS_PROFILE_NAME}
結果
The config profile (jawsug-cli-user) could not be found
コマンド
aws configure get region \
    --profile ${USERS_PROFILE_NAME}
結果
The config profile (jawsug-cli-user) could not be found

1.4. プロファイルの作成

変数の確認

コマンド
cat << ETX

    USER_NAME: ${USER_NAME}
    ACCESS_KEY: ${USER_ACCESS_KEY}
    SECRET_ACCESS_KEY: ${USER_SECRET_ACCESS_KEY}
    REGION: ${AWS_DEFAULT_REGION}

ETX
結果
    USER_NAME: jawsug-cli-user
    ACCESS_KEY: ********************
    SECRET_ACCESS_KEY: ***********************************
    REGION: ap-northeast-1

プロファイルの作成

コマンド
aws configure set aws_access_key_id ${USER_ACCESS_KEY} \
    --profile ${USERS_PROFILE_NAME}
結果
(戻り値無し)
コマンド
aws configure set aws_secret_access_key ${USER_SECRET_ACCESS_KEY} \
    --profile ${USERS_PROFILE_NAME}
結果
(戻り値無し)
コマンド
aws configure set region ${AWS_DEFAULT_REGION} \
    --profile ${USERS_PROFILE_NAME}
結果
(戻り値無し)

1.5. 認証情報の確認(.aws/credentials)

コマンド
cat ~/.aws/credentials
結果(例)
[jawsug-cli-user]
aws_access_key_id = ********************
aws_secret_access_key = ***********************************

1.6. 認証情報の確認(.aws/config)

コマンド
cat ~/.aws/config
結果(例)
[profile jawsug-cli-user]
region = ap-northeast-1

2. ユーザの切り替え

一般ユーザのプロファイルに切り替えます。

2.1. 現在のユーザの確認

あとで現在の状態に戻るため、一応結果を控えておいてください。(以下の結果は、インスタンスプロファイルを利用している場合)

コマンド
aws configure list
結果(例)
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************CIIA         iam-role
secret_key     ****************wGIk         iam-role
    region           ap-northeast-1              env    AWS_DEFAULT_REGION

2.2. 切替後ユーザの確認

コマンド
cat << ETX

    USERS_PROFILE_NAME: ${USERS_PROFILE_NAME}

ETX
結果
    USERS_PROFILE_NAME: jawsug-cli-user

2.3. ユーザの切り替え

コマンド
export AWS_DEFAULT_PROFILE=${USERS_PROFILE_NAME}

2.4. 認証情報の確認

コマンド
aws configure list
結果
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile          jawsug-cli-user           manual    --profile
access_key     ****************QNVA shared-credentials-file
secret_key     ****************fTJ+ shared-credentials-file
    region           ap-northeast-1              env    AWS_DEFAULT_REGION

3. データの暗号化

3.1. データキーの生成

コマンド
aws kms generate-data-key \
    --key-id ${KEY_ID} \
    --key-spec AES_256 \
    > ${KEY_ID}.json \
    && cat ${KEY_ID}.json
結果
{
    "Plaintext": "********************************************",
    "KeyId": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
    "CiphertextBlob": "AQEDAHiCRznQUHSBmR0PbOH+dC1yCIXtowgxaDBtcteu1VzqOAAAAH4wfAYJKoZIhvcNAQcGoG8wbQIBADBoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDMlTZXU8X/5Zct1vaAIBEIA7dZiDXkUn8BeUkDNidSwHfg9uxGEu9LJsyL1lMlJt3+J5zZAjw9FCy8qPt//8BOHkyD4Ivxm2rn2DEg0="
}

3.2. データキー(平文)の取り出し

暗号化が完了したら削除する予定です。

コマンド
PLAIN_DATA_KEY_FILE_NAME='plaintext.txt'
コマンド
cat ${KEY_ID}.json | jp.py 'Plaintext' | sed 's/"//g' \
    > ${PLAIN_DATA_KEY_FILE_NAME} \
    && cat ${PLAIN_DATA_KEY_FILE_NAME}

3.3. データキー(暗号化済)の取り出し

暗号化が完了しても、復号化の際に必要になるため削除せずに保管します。

コマンド
CIPHER_DATA_KEY_FILE_NAME='ciphertext_blob.txt'

データキーの復号化を想定し、BASE64でエンコードしておきます。

コマンド
cat ${KEY_ID}.json | jp.py 'CiphertextBlob' | sed 's/"//g' \
    | base64 --decode > ${CIPHER_DATA_KEY_FILE_NAME} \
    && cat ${CIPHER_DATA_KEY_FILE_NAME}

3.4. データファイルの生成

暗号化対象のテキストファイルを生成します。

コマンド
PLAIN_TEXT_FILE_NAME='non_encrypted.txt'

cat << EOF > ${PLAIN_TEXT_FILE_NAME}
hello, world!
EOF

cat ${PLAIN_TEXT_FILE_NAME}

3.5. 出力先ファイル名の指定

コマンド
ENCRYPTED_TEXT_FILE_NAME='encrypted.txt'

3.6. データの暗号化

変数の確認

コマンド
cat << ETX

    INPUT_FILE_NAME: ${PLAIN_TEXT_FILE_NAME}
    INPUT_FILE: $(cat ${PLAIN_TEXT_FILE_NAME})
    OUTPUT_FILE_NAME: ${ENCRYPTED_TEXT_FILE_NAME}
    PLAIN_DATA_KEY_FILE_NAME: ${PLAIN_DATA_KEY_FILE_NAME}
    PLAIN_DATA_KEY: $(cat ${PLAIN_DATA_KEY_FILE_NAME})

ETX
結果
    INPUT_FILE_NAME: non_encrypted.txt
    INPUT_FILE: hello, world!
    OUTPUT_FILE_NAME: encrypted.txt
    PLAIN_DATA_KEY_FILE_NAME: plaintext.txt
    PLAIN_DATA_KEY: ********************************************

データの暗号化

コマンド
openssl enc \
    -e \
    -aes-256-ecb \
    -in ${PLAIN_TEXT_FILE_NAME} \
    -out ${ENCRYPTED_TEXT_FILE_NAME} \
    -pass file:${PLAIN_DATA_KEY_FILE_NAME}
結果
(戻り値無し)

3.7. データキー(平文)の破棄

平文のデータキーはきちんと削除しましょう。

コマンド
rm ${PLAIN_DATA_KEY_FILE_NAME}

4. データの復号化

4.1. データキー(暗号化済)の復号化

コマンド
DECRYPTED_DATA_KEY_FILE_NAME='decrypted_plaintext.txt'
コマンド
aws kms decrypt \
    --ciphertext-blob fileb://${CIPHER_DATA_KEY_FILE_NAME} \
    --query Plaintext \
    --output text \
    > ${DECRYPTED_DATA_KEY_FILE_NAME} \
    && cat ${DECRYPTED_DATA_KEY_FILE_NAME}
結果
********************************************

結果がgenerate-data-keyで出力したPlaintextと一致していることを確認します。

コマンド
cat ${KEY_ID}.json | jp.py 'Plaintext' | sed 's/"//g' \
    > ${PLAIN_DATA_KEY_FILE_NAME} \
    && cat ${PLAIN_DATA_KEY_FILE_NAME}
コマンド
diff ${DECRYPTED_DATA_KEY_FILE_NAME} ${PLAIN_DATA_KEY_FILE_NAME}
結果
(戻り値無し)

4.2. データの復号化

復号化したデータキーで暗号化した文章を復号化します。

コマンド
openssl enc \
    -d \
    -aes-256-ecb \
    -in ${ENCRYPTED_TEXT_FILE_NAME} \
    -out ${PLAIN_DATA_KEY_FILE_NAME} \
    -pass file:${DECRYPTED_DATA_KEY_FILE_NAME} \
    && cat ${PLAIN_DATA_KEY_FILE_NAME}
結果
hello, world!

4.3. データキー(平文)の破棄

平文のデータキーはきちんと削除しましょう。
(大事なことなので2度言いました。)

コマンド
rm ${DECRYPTED_DATA_KEY_FILE_NAME}
rm ${PLAIN_DATA_KEY_FILE_NAME}

以上

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away