【AWSセキュリティ基礎】AWS Key Management Service(KMS)

# KMSとは
データ暗号化に使用される暗号化キーの作成と管理を行う、AWSのマネージドサービス。
AWSのサービスで暗号化処理が行われる場合、ほとんどはこのKMSのキーが使用される。

## KMSを使用するメリット
- マネージドサービスのため、以下の管理がAWS側の責任となる
    - キーの可用性
    - 物理的セキュリティ
    - ハードウェア管理
- 暗号化キーの操作履歴がすべてCloudTrailに保存されるため、監査やコンプライアンスの要件にも応えることができる

## KMSの暗号化の仕組み
KMSでは、Envelope Encryption(エンベロープ暗号化)という仕組みが採用されている。
具体的には、CMKとCDKという2種類のキーを使用し、データを暗号化するキー(CDK)をさらに別のキー(CMK)で暗号化するという仕組み。

### データ暗号化の流れ
![キャプチャ_1115.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494752/014cfb11-8d90-cc22-871a-327261f7b520.png)

①アプリケーションからGanerateDataKeyオペレーションを使用してCDKを生成
②KMSでCMKが複号される
③復号されたCMKを使用し、生成されたCDKを暗号化
④アプリケーションにプレーンなCDKと暗号化されたCDKが返される
⑤④で返されたプレーンなCDKを使用して対象データを暗号化。この時点でプレーンなCDKとプレーンなデータは必ず破棄される。
⑥暗号化されたデータと暗号化されたCDKをDBに格納する

### データ復号の流れ
![キャプチャ_1115-02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494752/2200540f-1fc6-0e73-bbdb-2e2c89b9b3be.png)

①アプリケーションからDecryptオペレーションを使用してKMSからCMKを取り出す
②保存していた暗号化CDKを復号する
③復号したCDKを使用して、保存していた暗号化データを復号する

## CMKのタイプ
CMKには以下3つのタイプがある。

- カスタマー管理CMK
- AWS管理CMK
- AWS所有CMK

### カスタマー管理CMK
- カスタマー側（AWS利用者）が作成・所有・管理するCMK
- ユーザが開発したアプリケーションでデータを暗号化する際に使用する
- 以下の操作が可能
    - キーポリシーやIAMポリシーによるアクセス制御
    - 有効化と無効化
    - ローテーション
    - エイリアス作成
    - 削除のスケジューリング
    - 1年ごとの自動ローテーション有効化/無効化

### AWS管理CMK
- AWSサービスが利用者に代わって作成・管理・使用するCMK
- KMSのマネジメントコンソール上に”aws/[サービス名]”といった形で表示される
    - 例：redshiftで使用されるCMK→「aws/redshift」
    - この仕様により、カスタマー管理CMKでは「aws」から始まるCMKは作成できない
- 可能な操作はキーポリシーの表示のみ
- 3年ごとにAWS側で自動ローテーションされる

### AWS所有CMK
- アカウントに関係なくAWSが所有し管理しているCMK
- 利用者側からは見えない
- AWSサービスが裏側で暗号化のために使用するもの

### CMK比較表
| CMKのタイプ | CMK管理 | AWSアカウント内 | メタデータ表示 | ローテーション |
|:-:|:-:|:-:|:-:|:-:|
|カスタマー管理CMK|〇|〇|〇|1年間|
|AWS管理CMK|×|〇|〇|3年間|
|AWS所有CMK|×|×|×|-|


## CMKの有効化と無効化
カスタマー管理のCMKは、無効化と、無効化後の再有効化ができる（※AWS管理のCMKは永続的に有効化されていて、無効化できない）。
そのため、CMKを削除するのが不安な場合はまず無効化を実施し、そのCMKを使用していない（エラーが発生していない）ことを確認するのが望ましい。

## CMKの削除
カスタマー管理CMKは削除することができる。
ただし削除したCMKは元に戻せないため、2度と使用することはできない。
これは対象のCMKで暗号化したデータが復号できなくなることを意味しているので、非常にリスクが高い。

そのため、CMKの削除は**即時実行ができない**仕様となっており、7～30日の待機期間が設けられている（デフォルトは30日間）。
待機期間はCMKの削除は実行されず、「削除保留中」というステータスとなる。
このステータスの間、対象のCMKを使用することはできない。

## CMKのローテーション
KMSには自動キーローテーションという機能がある。
自動キーローテーションを有効化すると、1年ごとにキーが自動でローテーションされる（1年という期間は変更することができない）。

ローテーションにより新しいCMKが作成されるが、もちろんローテーション前のキーで暗号化していたデータも問題なく復号することができる。
これは、CMKがローテーション前の古いキー情報も保持しているためである。
この、過去の情報を保持しているキーを**「バッキングキー」**と呼ぶ。
古いキーで暗号化されたデータは新しいキーで再暗号化されるわけではなく、暗号化時には最新のキーが使われ、復号時には暗号化に使用したバッキングキーが使用される仕組みとなっている。

## ポリシーによるアクセス制御
CMKのアクセス制御にはキーポリシーとIAMポリシーを使用することができ、それぞれ以下の役割を担っている。

- **キーポリシー**：CMKを対象にアクセス制御を行う
- **IAMポリシー**：CMKを使用する側（IAMユーザーやIAMロール）に対してアクセス制御を行う

キーポリシーとIAMポリシー両方で許可された操作のみ可能となるため、これらを上手く組み合わせてアクセス制御を行うことが必要。

### キーポリシーの書き方
キーポリシーは以下のように記載する。基本的にはIAMポリシーの書き方と同様。

```
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "statement identifier",
    "Effect": "effect",
    "Principal": "principal",
    "Action": "action",
    "Resource": "resource",
    "Condition": {"condition operator": {"condition context key": "context key value"}}
  }]
}
```
- 各ステートメントの内容
    - Sid：任意の識別子。（オプション）
    - Effect：AllowもしくはDenyを記載する。（必須）
    - Principal：キーポリシーに書かれた権限を利用できるのは誰か指定する。（必須）
    - Action：AllowまたはDenyするAPIを指定する。（必須）
    - Resource：対象リソースを指定する。（必須）
    - Condition：キーポリシーを有効にするために満たす必要がある要件を指定する。（オプション）

## クライアントサイド暗号化とサーバーサイド暗号化
KMSを利用した暗号化は、暗号化を行うタイミングにより、「クライアントサイド暗号化（Client-Side-Encryption）」と「サーバーサイド暗号化（Server-Side-Encryption）」の2種類に分けられる。

### クライアントサイド暗号化
- ユーザーがアプリケーションで暗号化を行う場合のこと
- SDKでKMSのAPIを呼び出し、取り出したキーでデータを暗号化する
- カスタマー管理CMKを使用することになる
- 暗号化した後、そのデータは通信経路上も暗号化された状態となり、よりセキュアにデータを扱うことができる
- アプリケーションに暗号化の処理を加える必要があるため手間がかかる

### サーバーサイド暗号化
- AWSの各サービスが提供する暗号化機能を使用する場合のこと
- AWSサービスがデータを受信後、自動的に暗号化する
- カスタマー管理CMKまたはAWS管理CMKを使用することになる
- AWSサービスまでの通信経路は暗号化されないため、クライアントサイド暗号化に比べるとセキュリティ強度が落ちる
- アプリケーションに暗号化の処理を加える必要がないため、簡単に実装できる


# 参考

https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947#

https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policies.html