[JAWS-UG CLI] Amazon KMS 入門 おまけ キーマテリアルのインポート

# このハンズオンについて

この手順は、[JAWS-UG CLI専門支部 #58 KMS入門](https://manage.doorkeeper.jp/groups/jawsug-cli/events/41911)で実施する予定のものです。


# 前提条件

## 必要な権限

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

- KMSに対するフルコントロール権限


# 0. 準備

## 0.1. リージョンを指定

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

## 0.2. 資格情報を確認


```bash:コマンド
aws configure list
```

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

```text:結果
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. バージョン確認

```bash:コマンド
aws --version
```

```text:結果
aws-cli/1.10.56 Python/2.7.10 Linux/4.4.15-25.57.amzn1.x86_64 botocore/1.4.46
```

## 0.4. バージョンアップ（必要に応じて）

```bash:コマンド
sudo pip install -U awscli
```


# 1. カスタマーマスターキーの作成（キーマテリアルを外部からインポートする場合）

## 1.1. カスタマーマスターキーの作成

originにEXTERNALを指定します。

```bash:コマンド
KEY_ID=$(aws kms create-key \
    --origin EXTERNAL \
    --query KeyMetadata.KeyId \
    --output text) \
    && echo ${KEY_ID}
```

```text:結果（例）
********-****-****-****-************
```


## 1.2. キーの確認

KeyStateがPendingImportになっています。

```bash:コマンド
aws kms describe-key \
    --key-id ${KEY_ID}
```

```json:結果
{
    "KeyMetadata": {
        "Origin": "EXTERNAL",
        "KeyId": "********-****-****-****-************",
        "Description": "JAWS-UG CLI 58 KMS at Co-Edo",
        "Enabled": false,
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "PendingImport",
        "CreationDate": 1470985986.394,
        "Arn": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
        "AWSAccountId": "************"
    }
}
```

## 1.3. インポートパラメータを保存するファイル名を指定

```bash:コマンド
IMPORT_PARAM_FILE_NAME='import_param.json'
```


## 1.4. インポートパラメータの取得

詳細はAPIのリファレンスを確認した方がよいです。

http://docs.aws.amazon.com/kms/latest/APIReference/API_GetParametersForImport.html

```bash:コマンド
aws kms get-parameters-for-import \
    --key-id ${KEY_ID} \
    --wrapping-algorithm RSAES_OAEP_SHA_1 \
    --wrapping-key-spec RSA_2048 \
    > ${IMPORT_PARAM_FILE_NAME} \
    && cat ${IMPORT_PARAM_FILE_NAME}
```

```json:結果
{
    "ParametersValidTo": 1471077220.188,
    "PublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuIwZiZaJqu59kMDvmBDMdjizFaIN4tWlwQHQ1IkS/kPPMfcpGd7aXl7BwawwTHPaO9J5/NsCSy0aIQgsnXv0uuxMdGmRDe+72P5XhguYzznJMrTtNPzW+uXOGQUWpt/o/1NhY372gCmrylopEPU73eLWDaCAngzBG0KeaS2ApR+9FUnsg3Y2jad0MqznCdi8fD64l1udAlBpHyprX2sHhZkrqKJRdkUdxlWGz9DfbIFXHltKjr4hoYpE5mmquR2YMWTi3rO3kq0bsrahCaqkfxKy82W+WPFh5spS0xDUZTsZW+44/WkZGIFDyFQbRRD5WwxkKu2yGFG9RmxVxdbPUwIDAQAB",
    "KeyId": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
    "ImportToken": "(too long token...)"
}
```


## 1.5. キーマテリアルを生成（インポート用）

```bash:コマンド
KEY_MATERIAL_FILE_NAME='plain_text_aes_key.bin'

openssl rand -out ${KEY_MATERIAL_FILE_NAME} 32
```

```text:結果
（戻り値無し）
```

## 1.6. キーマテリアルをラッピングキーで暗号化


### ファイル名の指定

```bash:コマンド
DECODED_WRAPPING_KEY_FILE_NAME="wrappingKey_${KEY_ID}.bin"
ENCRYPTED_KEY_MATERIAL_FILE_NAME='enc.aes.key'
```

### ラッピングキーの抽出

base64でエンコードされているため、デコードします。

http://docs.aws.amazon.com/kms/latest/APIReference/API_GetParametersForImport.html#API_GetParametersForImport_ResponseElements

```bash:コマンド
cat ${IMPORT_PARAM_FILE_NAME} \
    | jq -r .PublicKey \
    | openssl enc -d -base64 -A \
    > ${DECODED_WRAPPING_KEY_FILE_NAME} \
    && cat ${DECODED_WRAPPING_KEY_FILE_NAME}
```

```text:結果
（省略）
```


### 変数を確認

```bash:コマンド
cat << ETX

    KEY_MATERIAL_FILE_NAME: ${KEY_MATERIAL_FILE_NAME}
    DECODED_WRAPPING_KEY_FILE_NAME: ${DECODED_WRAPPING_KEY_FILE_NAME}
    ENCRYPTED_KEY_MATERIAL_FILE_NAME: ${ENCRYPTED_KEY_MATERIAL_FILE_NAME}

ETX
```

```text:結果

    KEY_MATERIAL_FILE_NAME: plain_text_aes_key.bin
    DECODED_WRAPPING_KEY_FILE_NAME: wrappingKey_********-****-****-****-************.bin
    ENCRYPTED_KEY_MATERIAL_FILE_NAME: enc.aes.key

``` 

### キーマテリアルを暗号化

```bash:コマンド
openssl rsautl -encrypt \
    -in ${KEY_MATERIAL_FILE_NAME} \
    -oaep \
    -pubin \
    -inkey ${DECODED_WRAPPING_KEY_FILE_NAME} \
    -keyform DER \
    -out ${ENCRYPTED_KEY_MATERIAL_FILE_NAME} \
    && cat ${ENCRYPTED_KEY_MATERIAL_FILE_NAME}
```

```text:結果
（省略）
```


## 1.7. キーマテリアルのインポート

### インポートトークンのファイル名の指定

```bash:コマンド
DECODED_IMPORT_TOKEN_FILE_NAME="import_token_${KEY_ID}.bin"
```

### インポートトークンの抽出

base64でエンコードされているため、デコードします。

```bash:コマンド
cat ${IMPORT_PARAM_FILE_NAME} \
    | jq -r .ImportToken \
    | openssl enc -d -base64 -A \
    > ${DECODED_IMPORT_TOKEN_FILE_NAME} \
    && cat ${DECODED_IMPORT_TOKEN_FILE_NAME}
```

```text:結果
（省略）
```

### 有効期限の指定

現在時刻から365日後を有効期限とします。

```bash:コマンド
((VALID_TO = $(date +'%s') + 31536000)) \
    && echo ${VALID_TO} \
    | awk '{ print strftime("%c", $1); }'
```

```text:結果
Sun 13 Aug 2017 09:30:48 AM UTC
```

### 変数を確認

```bash:コマンド
cat << ETX

    KEY_ID: ${KEY_ID}
    DECODED_IMPORT_TOKEN_FILE_NAME: ${DECODED_IMPORT_TOKEN_FILE_NAME}
    ENCRYPTED_KEY_MATERIAL_FILE_NAME: ${ENCRYPTED_KEY_MATERIAL_FILE_NAME}
    VALID_TO: ${VALID_TO}

ETX
```

```text:結果

    KEY_ID: ********-****-****-****-************
    DECODED_IMPORT_TOKEN_FILE_NAME: import_token_********-****-****-****-************.bin
    ENCRYPTED_KEY_MATERIAL_FILE_NAME: enc.aes.key
    VALID_TO: 1502616803

```

### キーマテリアルのインポート

```bash:コマンド
aws kms import-key-material \
    --key-id ${KEY_ID} \
    --import-token fileb://${DECODED_IMPORT_TOKEN_FILE_NAME} \
    --encrypted-key-material fileb://${ENCRYPTED_KEY_MATERIAL_FILE_NAME} \
    --valid-to ${VALID_TO}
```


```text:結果
（戻り値無し）
```

## 1.8. キーの確認

KeyStateがEnabledになっています。

```bash:コマンド
aws kms describe-key \
    --key-id ${KEY_ID}
```

```json:結果
{
    "KeyMetadata": {
        "Origin": "EXTERNAL",
        "KeyId": "********-****-****-****-************",
        "Description": "",
        "ExpirationModel": "KEY_MATERIAL_EXPIRES",
        "ValidTo": 1471164509.0,
        "Enabled": true,
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "CreationDate": 1471078089.774,
        "Arn": "arn:aws:kms:ap-northeast-1:************:key/********-****-****-****-************",
        "AWSAccountId": "************"
    }
}
```

以上