【AWS】賢くセキュアに鍵管理をしよう(AWS KMS)
2025年12月23日

「先生!IAM Policyでkms:Decrypt権限書いているのにAccess Deniedが表示されてしまいます!」 という経験がある方向けの記事です。
AWS KMS(Key Management Service)とは?
簡単に言うと、「データの暗号化に使う「鍵」を、安全に作成・保管・管理してくれるAWSのサービス」のことです。
セキュリティの専門的な知識がなくても、AWS上のデータを簡単に、かつ極めて高いセキュリティレベルで暗号化・保護することができます。
KMSでなにができるの?
①AWSサービスと密に連携(最大のメリット)
KMSは、他のAWSと深く統合されています。多くの場合、設定画面で「暗号化する」にチェックをいれるだけで、KMSが裏で自動的に鍵を作り、データを暗号化してくれます。便利ですね。
・S3:アップロードしたファイルを自動暗号化
・EBS:EC2のディスクを暗号化
・RDS:データベースの中身を暗号化
②「誰が鍵を使えるか」を細かく制御
「鍵」があっても、みんながみんな使えたら意味がないですよね。KMSでは「キーポリシー」という機能を使って、細かく権限を設定できます。
・・・いや、それIAMで制御すれば良くね?
っていう鋭い疑問が浮かぶ人もいるかもしれません。
たしかにIAMでリソースに対するアクセス制御ができるのは正しいです。
ですが、AWSの世界ではKMSのキー権限が最強なのです。というか、守る対象が若干違うのです。
例えば、暗号化されたS3バケット(kudo-bucket)へのアクセスを制御することを考えてみてください。
あなたは、IAMポリシーでkudo-bucketへのAdmin権限を持っています。ですが、キーポリシーではあなたは許可されていません。
①IAMの判定
あなた:「kudo-bucketからファイルをダウンロードしたい!」
IAM:「あなたはkudo-bucketのAdmin権限を持ってるから、kudo-bucketに触っていいですよ」
結果:バケットまでは辿り着けます
②KMSの判定
あなた: 「ダウンロードしたファイルは暗号化されてるから、復号(解読)したい! 鍵をください!」
キーポリシー: 「リストにあなたの名前はないですね。この鍵の使用は許可できません。」
結果: 「Access Denied(アクセス拒否)」というエラーが出て、ファイルの中身は見られません。
トップに記載していた、IAMのkms:Decryptがあるのにアクセス拒否されちゃう~っていうのは上記の理解が浅い場合に発生してしまうということです。あるあるらしいですね。
③「誰がいつ鍵を使ったか」を記録
セキュリティにおいて「いつ、誰が、どの鍵を使ったか」の記録は非常に重要です。
KMSは、AWS CloudTrailというサービスと連携し、鍵の使用履歴をすべてログとして残します。
CloudTrailの詳細な説明は省略しますが、誰がリソースをどう操作したかをロギングできる優秀なヤツです。
KMSはどうやって使うの?
今回は、実務で頻繁に行うであろう「S3バケットのデータを、自分たちで作成した鍵(CMK)で暗号化・保護」するというシナリオで解説します。実際にやってみましょう!
①鍵を作成
マネジメントコンソールからKMS画面に移動し、鍵を作成します。
「キーの作成」を選択してください。

キーのタイプ:「推奨」
キーの使用法:「暗号化および複合化」を選択してください

エイリアスにはなるべくわかりやすい名前をつけてあげてください。その他は設定しなくても大丈夫です。

ここでキーを管理できるIAMを選択できます。自身がIAMユーザでログインしているのであれば自身のIAMユーザを選択、適宜運用用のロールがあるのであればそちらを選択してください。

次はキーユーザーの選択ですね。先ほどの管理者と混乱するかもしれないので整理します。

・ 管理者(さっきの画面): 鍵の捨て方や、誰に貸すかを決める人
・ユーザー(この画面): 実際にその鍵を手に取って、金庫(S3など)を開け閉めする人
という違いがあります。
今回は同じユーザを選択しておきましょうか。
次に進むと、なにやら怖い画面に来ました。

基本的にポリシーは今回のテスト目的であれば、操作は必要ございません。Principalに自身のアカウントIDがあることさえ確認できればOKです。
これは、キーポリシーを間違えたときに、アカウント管理者であればIAMポリシー経由で修正できるよ~っていうセーフティネットの役割を果たしています。

確認が完了したら、完了ボタンを押して完成です!
わーい!
次に、暗号化させたいS3バケットを選択しましょう。バケットがない方は新しく作ってあげてください。(作り方がわからない方はこちらの記事が参考になります)

プロパティタブより、デフォルトの暗号化を確認してください。今はS3側で暗号化されていますね。

次に、暗号化タイプにて「SSE-KMS」を選択し、AWS KMSキーに先ほど作成したキーを入力します。

その後に、バケットに適当なファイルをアップロードしてください。

アップロードしたオブジェクトの詳細画面に遷移し、SSE-KMSで暗号化されていたら成功です!
お疲れ様でした。

KMSにおける鍵の種類
今更ですが、今回はカスタマーマネージドキーというものを作成しました。ですが、実はKMSには鍵の種類がいくつかございます。
| 種類 | 説明 | メリット / デメリット |
|---|---|---|
| AWS 所有のキー | AWSが裏側で共有して使っている鍵 | 完全無料。 ただし、キーポリシーの変更やログの確認が一切できない。 |
| AWS マネージドキー | 特定のサービス(S3用、EBS用など)ごとにAWSが自動作成する鍵 | 保管料無料。 ログは見れるが、キーポリシーの変更はできない。 |
| カスタマーマネージドキー | (今回作ったもの) ユーザーが作成・管理する鍵 | 月1ドル。 権限を細かく制御でき、最もセキュア。 |
AWS所有のキーはユーザ側で確認できないので、ないと思ってもらって良い(?)のですが、AWSマネージドキーはマネジメントコンソールからも確認できます。S3やEBSで然るべき設定をするとAWSが自動で作成してくれます。
おそらく実務だとCMKを作成して管理するのがもっとも一般的だと思います。最小権限の原則を担保するためにも、ユーザ側でポリシーを管理できた方がよりセキュアですよね。
マルチリージョンキー
また、カスタマーマネージドキーを作成する際に「詳細オプション」にて、「リージョン設定」を行うと、マルチリージョンキーを作成することができます。これを選ぶと、作成後に他のリージョンに「レプリカ」を作成できるようになります。作成したリージョンの分だけ課金される仕組みになっています。

KMS API 一覧
KMSのAPIには、下記のようなものがあります。ポリシーの設定、CloudTrailのログなどの確認に使用されます。
①データ操作系
| API名 | 主な役割 | 利用シーン |
|---|---|---|
GenerateDataKey | データキーの発行 | クライアントサイド暗号化の開始時。 |
Encrypt | データの直接暗号化 | 4KB以下の小規模なデータ(パスワード、設定値など)の保護。 |
Decrypt | データの復号 | 暗号化されたデータ、またはデータキーを元に戻す時。 |
ReEncrypt | 鍵の掛け替え | 別のKMSキーで暗号化し直す(データを生に戻さずKMS内で処理)。 |
GenerateRandom | 乱数の生成 | 暗号学的に安全なランダム値が欲しい時。 |
Sign | デジタル署名 | メッセージに対して署名を作成する(非対称鍵の場合)。 |
Verify | 署名の検証 | 署名が正しいかを確認する(非対称鍵の場合)。 |
②キー管理系
| API名 | 主な役割 | 備考 |
|---|---|---|
CreateKey | KMSキーの新規作成 | マルチリージョンかどうかもここで指定。 |
DescribeKey | 詳細情報の取得 | キーの状態(有効/無効)や作成日を確認。 |
EnableKey | キーの有効化 | 無効化していたキーを再度使えるようにする。 |
DisableKey | キーの無効化 | 削除はしたくないが、一時的に使わせたくない時。 |
ScheduleKeyDeletion | 削除予約 | 待機期間(7〜30日)を経て削除。即時削除は不可。 |
UpdateKeyDescription | 説明文の更新 | キーの用途メモなどを書き換える。 |
③ポリシー・アクセス制御系
| API名 | 主な役割 | 利用シーン |
|---|---|---|
PutKeyPolicy | キーポリシーの設定 | 鍵に直接紐づくアクセス権限を上書き。 |
GetKeyPolicy | キーポリシーの取得 | 現在の設定内容を確認。 |
CreateAlias | エイリアスの作成 | キーID(長い文字列)に別名(alias/my-key)を付ける。 |
CreateGrant | 権限の一時付与 | 他のユーザーやサービスに、特定の権限を一時的に委譲。 |
④マルチリージョン・インポート系
| API名 | 主な役割 | 備考 |
|---|---|---|
ReplicateKey | レプリカの作成 | マルチリージョンキーを他リージョンに複製。 |
GetParametersForImport | インポート準備 | 外部から鍵をインポートするための公開鍵とトークンを取得。 |
ImportKeyMaterial | 鍵マテリアルの注入 | 自分で用意した「鍵のタネ」をKMSにアップロード。 |
クライアント暗号化とサーバサイド暗号化
KMSを利用した暗号化には、次の 2種類があります。
- ▸クライアントサイド暗号化(Client-Side-Encryption: CSE)
- ▸アプリケーション側で暗号化を実施します。
- ▸アプリケーション側で暗号化済みデータを送信するので、AWS までの通信経路上は暗号化された状態となります。
- ▸クライアントサイドで暗号化/復号の処理が必要なため、実装に手間がかかります
- ▸サーバサイド暗号化(Server-Side-Encryption: SSE)
- ▸AWS の各サービスが提供する暗号化を利用します。(例:S3 バケット)
後述する「インポートキー」と内容が混乱してしまいそうですが、あくまで鍵の発行はAWS側で行い、「自分たち側」か「AWS側」、どちら側で暗号化する?という単純なお話です。
「KMSキー」と「データキー」という概念
ここからは少し話が難しくなります。
実は、KMSの鍵で直接大きなファイルを暗号化しているわけではありません。なぜなら、思いデータをわざわざKMSに送って暗号化すると、遅延もするしコストもかかっちゃうのです。
そこで賢いAWSは「エンベロープ暗号化」という手法を使います。
(エンベロープ暗号化の詳しい説明:エンベロープ暗号化)
エンベロープ暗号化の流れ(イメージ:封筒と鍵)
①データキーの作成: KMSが「使い捨ての小さな鍵(データキー)」を発行
②データの暗号化: その小さな鍵で、手元にある大きなデータを高速に暗号化
③鍵の保護: 使い終わった「小さな鍵」を、KMSキー(親鍵)で暗号化して、データと一緒に保存
なんでこんな面倒くさいことするんだよ!
前述したように、なるべく「データ本体」は手元に残しておきたいのです。なので、「データ本体」は手元で高速に処理しつつ、「鍵の管理」だけをKMSに任せることで、セキュリティと速度を両立しているんです。めっちゃ賢くないですか?
「インポートキー」の概念
もっとマニアックな話をします。 KMSでは、「自分たちで用意した鍵の素材をAWSに持ち込む」 ことができます。技術的には高度なのでなかなか用いることはないかもしれませんが、金融機関や政府機関など、極めて高いセキュリティ要件が求められるプロジェクトで使用されます。
なんでわざわざインポートするんだよ!AWSの鍵使えよ!
それな!
AWSのHSMで生成した鍵でもセキュリティ上は全く問題ございません。
なので、「いや別に、AWSを信じていないわけじゃないけど・・///」というコンプライアンス上の理由がほとんどです。
要件としてよく見るのは「Azureなどと連携したいので、マルチクラウドで共通利用する」目的とかですね。クラウドを跨いで暗号化データをやり取りしたいということです。
どうやって作成するの?
特殊な手順のため、実際には実行しませんが、下記の手順で進めます。
①KMSで「空の箱」を作る: KMS上で「キーマテリアルなし」のキー(インポート用)を作成します。
②ラッピングキーを取得する: AWSから「この公開鍵で、あなたの鍵素材を包んで(暗号化して)送ってね」という「ラッピング用の鍵」と「インポートトークン」をダウンロードします。
③手元で鍵を包む(ラッピング): 自分のPCやサーバーにある鍵素材を、手順2の公開鍵を使って暗号化します。
④AWSにアップロードする: 暗号化された鍵素材とトークンをAWSにアップロードします。これで初めてKMSで鍵が使えるようになります。
もちろんだが、怖い注意点もある
- ▸鍵の管理責任は100%自分にある
- ▸自動ローテーションが使えない
- ▸有効期限が切れると即座に鍵が使用できなくなる
ん-・・・
基本的には使わない方が良いね^_^
ここまで読んでいただいた方であれば、インポートキーにそこまでメリットは感じられなかったのではないでしょうか。
その感覚は割と正しくて、基本的に通常のKMSキーが安全ですし楽です。 要件上必要になった場合に使用するってイメージです。
いかがでしたでしょうか。
KMSによる鍵管理トラブルは現場の地雷原にもなりやすいそうなので、使用経験のある方でも良い復習になったのではないでしょうか。
読んでくださり誠にありがとうございました!