目次
AWS KMS 完全ガイド 2026
初心者から実務者向けの包括的解説
AWS KMS(Key Management Service) は、暗号鍵のライフサイクルを管理し、AWS サービス・アプリケーションから安全に暗号化を行う セキュリティの中核サービス です。FIPS 140-2 準拠の HSM で保護された鍵マテリアルは KMS から外部に出ることなく、API 経由でのみ使用できます。本ドキュメントは、KMS の概念・仕組み・エコシステム・最新動向を体系的に解説する包括的ガイドです。
ドキュメントの目的
本ガイドは以下を対象としています:
- 初心者向け: KMS とは何か、なぜ必要かを学びたい方
- 開発者向け: 暗号化・復号・署名を実装したい方
- SRE / インフラ向け: マルチリージョン鍵・鍵ローテーション・CloudHSM 連携を検討する方
- コンプライアンス向け: 鍵ポリシー・監査・暗号化コンプライアンスを満たしたい方
- 意思決定者向け: AWS KMS vs CloudHSM vs HashiCorp Vault の比較・投資判断
2026 年の KMS エコシステム
- External Key Store(XKS)拡張: CloudHSM 統合の深化、オンプレミス HSM 連携
- Post-Quantum Cryptography: 量子耐性暗号への対応準備
- AI 駆動鍵管理: 異常検知、キーローテーション推奨、ポリシー提案
- Cross-Account Multi-Region Keys: 複数アカウント×複数リージョンの統一鍵管理
- Grafana / Prometheus 統計: KMS メトリクスの可視化・アラート
定義
AWS 公式による定義:
“AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and manage cryptographic keys.”
複数の暗号化方式、アーキテクチャ、監査機能を提供し、ほぼすべての AWS サービスの暗号化基盤として機能します。
エディション
- AWS Managed KMS:共有 HSM、標準機能を無料提供(マニュアルローテーション必要)
- Customer Managed KMS:カスタマーが制御、ポリシー細分化、$1/月 + API 呼び出し
- CloudHSM 統合(XKS):外部 HSM 連携、FIPS 140-2 Level 3 準拠、高コスト
目次
- 概要
- KMS が解決する課題
- 主な特徴
- アーキテクチャ
- キータイプと種類
- Customer Managed Key vs AWS Managed Key
- Multi-Region Keys
- 主要ユースケース
- エンベロープ暗号化
- Data Key の使い方
- 暗号化操作
- Key Policy
- Grants
- Key Rotation
- CloudHSM 連携
- セキュリティ・監査
- モニタリング
- コスト
- 他の類似ツールとの比較
- クライアントとエコシステム
- ベストプラクティス
- トラブルシューティング
- 2025-2026 最新動向
- 学習リソース
- 実装例・活用シーン
- 導入ロードマップ
- 実装チェックリスト
- まとめ
- 参考文献
概要
初心者向けメモ: KMS は「暗号鍵の銀行」です。自社で鍵を管理しようとするとセキュリティ・運用リスクが増大しますが、KMS に委ねると「鍵マテリアルは永遠に HSM 内に閉じ込められ、外部に出ない」という強力なセキュリティ保証が得られます。その代わり、KMS API 経由でしか暗号化・復号ができません。
AWS KMS は、以下の機能を提供する統合暗号鍵管理サービスです。
- 鍵のライフサイクル管理:作成・ローテーション・削除
- ポリシーベースのアクセス制御:キーポリシーで誰が何を実行できるか制限
- エンベロープ暗号化:大容量データを効率的に暗号化
- マルチリージョン対応:クロスリージョンレプリケーション
- CloudTrail 統合:全操作の完全監査
- AWS サービス統合:S3、EBS、RDS など 100+ サービスが KMS 対応
KMS の位置づけ
【図1】AWS セキュリティスタックにおける KMS の位置:
graph TD
Apps[アプリケーション]
Apps -->|S3 データ| S3[Amazon S3]
Apps -->|DB 暗号化| RDS[Amazon RDS]
Apps -->|EBS 暗号化| EBS[Amazon EBS]
Apps -->|シークレット| SM[AWS Secrets Manager]
Apps -->|ログ暗号化| CloudWatch[CloudWatch Logs]
S3 --> KMS
RDS --> KMS
EBS --> KMS
SM --> KMS
CloudWatch --> KMS
KMS -->|鍵マテリアル保護| HSM[FIPS 140-2 HSM]
KMS -->|監査ログ| CloudTrail[AWS CloudTrail]
KMS -->|メトリクス| CW[Amazon CloudWatch]
KMS が解決する課題
| 課題 | 従来の方法 | KMS での解決 |
|---|---|---|
| 鍵管理の複雑性 | 鍵をアプリコードに埋め込む、鍵ローテーションを手動実行 | KMS が中央集約、自動ローテーション対応 |
| 鍵の漏洩リスク | 鍵をファイルシステム・ソース管理に保存 | 鍵は FIPS 140-2 HSM 内に密閉、外部に出ない |
| 規制要件への対応 | 鍵監査の記録・証拠が不十分 | CloudTrail で完全な監査証跡、コンプライアンス対応 |
| 複数テナント環境の鍵分離 | 全データに同じ鍵、テナント間分離が困難 | テナント別にカスタマーマネージドキーを割当可 |
| 災害復旧時の鍵復旧 | 鍵をバックアップするため鍵の外部化が必要 | マルチリージョンキーで自動レプリケーション |
| エンタープライズ規格への準拠 | 物理 HSM の購入・運用が必要(コスト高) | マネージド HSM で低コスト FIPS 140-2 準拠 |
主な特徴
| 特徴 | 説明 |
|---|---|
| 鍵マテリアルは HSM に密閉 | FIPS 140-2 Level 3 準拠。鍵はサービス内に留まり、プレーンテキストで外部に出ない |
| エンベロープ暗号化 | Data Encryption Key(DEK)を用いた階層的暗号化。大容量データを高速に暗号化 |
| ポリシーベースアクセス制御 | IAM + キーポリシーで細粒度の権限管理。「このロールはこのキーの復号のみ可」の制限が可能 |
| 自動キーローテーション | CMK の場合、1 年ごとに自動でキーマテリアルを再生成。古いマテリアルは保持(復号可能) |
| CloudTrail 統合 | すべての KMS API 呼び出しを記録。「誰がいつ何の鍵で何を実行したか」の完全監査 |
| AWS サービス統合 | S3、EBS、RDS、Lambda、Secrets Manager など 100+ サービスが KMS ネイティブ対応 |
| マルチリージョン対応 | プライマリキーをレプリカキーとして複数リージョンに複製。災害復旧・グローバル展開に対応 |
| Grants 機構 | 一時的に特定の API 呼び出しをプリンシパルに委任。キーポリシー変更なしに権限付与 |
| クロスアカウント対応 | キーポリシーで別 AWS アカウントを許可。マルチアカウント環境での統一鍵管理 |
| データキー暗号化 | GenerateDataKey で平文キーと暗号化済みキーを同時取得。エンベロープ暗号化の基盤 |
アーキテクチャ
初心者向けメモ: KMS は 3 つのレイヤーで構成されます:
- コントロールプレーン:キーの作成・ポリシー管理(AWS コンソール)
- 管理プレーン:キーのメタデータ・ローテーション・ライフサイクル管理
- データプレーン:暗号化・復号 API(ユーザーアプリケーション)
【図2】KMS の 3 層アーキテクチャ:
graph TD
subgraph Control[コントロールプレーン]
CreateKey[Create Key]
UpdatePolicy[Update Policy]
ListKeys[List Keys]
end
subgraph Management[管理プレーン]
KeyStore[(KMS キーストア)]
Rotation[Key Rotation<br/>Manager]
Lifecycle[Lifecycle<br/>Manager]
Grant[Grant<br/>Manager]
end
subgraph Data[データプレーン]
Encrypt[Encrypt API]
Decrypt[Decrypt API]
GenerateDEK[GenerateDataKey]
Sign[Sign / Verify]
end
subgraph Audit[監査・監視]
CloudTrail[CloudTrail]
CloudWatch[CloudWatch]
CW[CloudWatch Events]
end
Control --> Management
Management --> KeyStore
Management --> Rotation
Management --> Lifecycle
Management --> Grant
Data --> KeyStore
Control --> Audit
Management --> Audit
Data --> Audit
KMS コンポーネント
1. AWS Managed Key(AWS 所有)
AWS が所有・管理する鍵。ユーザーが制御不可。
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
"KeyType": "AWS_OWNED",
"KeyState": "Enabled",
"Description": "Default key for S3 encryption"
}
✅ メリット:
- 無料(キー保管料なし)
- 自動ローテーション
- 簡単(デフォルト有効)
❌ デメリット:
- キーポリシー制御不可
- 監査ログ確認困難
- 複数テナント環境で個別制御不可
2. AWS Managed Key(AWS マネージド CMK)
AWS が管理するが、ユーザーが参照・設定可能な鍵。
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/2234bcde-23bc-45de-67fg-2345678901bc",
"KeyType": "AWS_MANAGED",
"KeyState": "Enabled",
"KeyRotationEnabled": true,
"Description": "AWS managed key for EBS encryption"
}
✅ メリット:
- $1/月(CMK 保管料)
- 自動ローテーション
- CloudTrail 記録
❌ デメリット:
- キーポリシーを編集できない
- ローテーション頻度を制御不可
3. Customer Managed Key(CMK)
ユーザーが完全に制御できる鍵。
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/3345cdef-34cd-56ef-78gh-3456789012cd",
"KeyType": "CUSTOMER_MANAGED",
"KeyState": "Enabled",
"KeyRotationEnabled": false,
"Description": "Custom managed key for application encryption",
"CustomerMasterKeySpec": "SYMMETRIC_DEFAULT"
}
✅ メリット:
- 完全なポリシー制御
- 手動/自動ローテーション選択可
- CloudTrail でキー使用状況を監査
❌ デメリット:
- $1/月 + API 呼び出し料金
- ポリシー管理の複雑性
キータイプと種類
1. 対称鍵(Symmetric Key)
最も一般的。同じ鍵で暗号化・復号。
{
"CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
"KeyUsage": "ENCRYPT_DECRYPT",
"Description": "Default symmetric key for S3/EBS"
}
用途:
- S3 バケット暗号化
- EBS ボリューム暗号化
- RDS データベース暗号化
- DynamoDB テーブル暗号化
- エンベロープ暗号化の MEK(Master Encryption Key)
特性:
- 🔒 高速、高セキュリティ
- 🔒 公開鍵暗号より効率的
- ❌ 公開鍵配布の課題(KMS でのみ使用)
2. 非対称鍵(Asymmetric Key)
公開鍵暗号。公開鍵で暗号化、秘密鍵で復号。
{
"CustomerMasterKeySpec": "RSA_2048",
"KeyUsage": "ENCRYPT_DECRYPT",
"Description": "RSA key for cross-environment encryption"
}
キータイプ:
| タイプ | 鍵長 | 用途 | パフォーマンス |
|---|---|---|---|
| RSA_2048 | 2048 ビット | TLS、一般的な公開鍵基盤 | 中程度 |
| RSA_3072 | 3072 ビット | 高セキュリティ要件 | 低い |
| RSA_4096 | 4096 ビット | 最高レベルセキュリティ | 非常に低い |
| ECC_NIST_P256 | 256 ビット | ECDSA 署名、楕円曲線 | 高速 |
| ECC_NIST_P384 | 384 ビット | 高度な楕円曲線暗号 | 高速 |
| ECC_NIST_P521 | 521 ビット | 最高度の楕円曲線 | 高速 |
用途:
- アプリケーション間データの暗号化(秘密鍵は KMS 保有)
- 署名・検証(データ完全性)
- クロスアカウント・クロスリージョン復号(秘密鍵は相手先で保有)
特性:
- ✅ 秘密鍵を KMS で保護
- ✅ 公開鍵は配布可能
- ❌ パフォーマンス劣化(対称鍵より遅い)
3. HMAC Key
Hash-based Message Authentication Code。メッセージ認証。
{
"KeySpec": "HMAC_224",
"KeyUsage": "SIGN_VERIFY",
"Description": "HMAC key for message authentication"
}
キータイプ:
| タイプ | ハッシュ | 出力長 |
|---|---|---|
| HMAC_224 | SHA-224 | 224 ビット |
| HMAC_256 | SHA-256 | 256 ビット |
| HMAC_384 | SHA-384 | 384 ビット |
| HMAC_512 | SHA-512 | 512 ビット |
用途:
- API リクエストの完全性検証
- JWT トークン署名
- メッセージ認証コード生成
4. External Key Material(BYOK)
Bring Your Own Key。外部で生成した鍵マテリアルをインポート。
# 1. インポートキーを作成
aws kms create-key --origin EXTERNAL
# 2. インポート用暗号化済みマテリアルを生成
aws kms get-public-key --key-id <key-id>
# 3. 暗号化済み鍵マテリアルをアップロード
aws kms import-key-material \
--key-id <key-id> \
--encrypted-key-material <encrypted-material> \
--import-token <import-token>
✅ メリット:
- オンプレミス HSM で生成した鍵を AWS で使用可
- コンプライアンス要件を満たす
❌ デメリット:
- 自動ローテーション不可(手動ローテーションのみ)
- KMS がマテリアルを生成していないため監査が複雑
5. CloudHSM Custom Key Store
外部 HSM との連携。CloudHSM で生成・管理した鍵を KMS で使用。
✅ メリット:
- CloudHSM の FIPS 140-2 Level 3 準拠
- オンプレミス HSM 統合
❌ デメリット:
- CloudHSM コスト($1.45/時間 + 初期投資)
- 設定の複雑性
Customer Managed Key vs AWS Managed Key
決断フロー:
Q1: キーポリシーで誰が使えるか制限したい?
├─ YES → Customer Managed Key
└─ NO → Q2
Q2: CloudTrail で詳細監査したい?
├─ YES → Customer Managed Key
└─ NO → Q3
Q3: 複数テナント・複数環境で鍵を分離したい?
├─ YES → Customer Managed Key
└─ NO → Q4
Q4: キーローテーション頻度を制御したい?
├─ YES → Customer Managed Key
└─ NO → AWS Managed Key で OK
| 要件 | AWS Managed Key | AWS Owned Key | Customer Managed Key |
|---|---|---|---|
| コスト | `1/月 | 無料 | `1/月 + API 呼び出し |
| ポリシー制御 | ❌ 不可 | ❌ 不可 | ✅ 完全制御 |
| ローテーション | ✅ 自動(不定期) | ✅ 自動(不定期) | ✅ 手動 or 自動(1 年) |
| CloudTrail 記録 | ⚠️ 限定的 | ❌ なし | ✅ 完全記録 |
| クロスアカウント | ❌ 不可 | ❌ 不可 | ✅ 可能 |
| 用途 | S3/EBS デフォルト | デフォルト暗号化 | ポリシー制御・監査が必要 |
Multi-Region Keys
クロスリージョンレプリケーション。同じキーマテリアルを複数リージョンに複製。
アーキテクチャ
graph TD
Primary["Primary Key<br/>(us-east-1)<br/>管理・ローテーション"]
Replica1["Replica Key<br/>(ap-northeast-1)<br/>読み取り専用"]
Replica2["Replica Key<br/>(eu-west-1)<br/>読み取り専用"]
Primary -->|キーマテリアル複製<br/>AWS バックボーン| Replica1
Primary -->|キーマテリアル複製<br/>AWS バックボーン| Replica2
Replica1 -.->|フェイルオーバー時<br/>管理権をプロモート| Replica1_Promoted["Replica Key<br/>(プライマリに昇格)"]
Replica2 -.->|フェイルオーバー時<br/>管理権をプロモート| Replica2_Promoted["Replica Key<br/>(プライマリに昇格)"]
特性
✅ メリット:
- 災害復旧: リージョン障害時、レプリカを即座にプライマリに昇格
- グローバル展開: ローカルリージョンの低レイテンシアクセス
- DynamoDB グローバルテーブル対応: 複数リージョンの DynamoDB テーブル暗号化
- クロスリージョン復号: 他リージョンで暗号化されたデータも復号可能(同じキーマテリアル)
❌ デメリット:
- キー ID が異なる:Primary と Replica は ARN が異なる(ただしマテリアルは同一)
- コスト増加:各リージョン
1/月(プライマリ1 + レプリカ $1 × リージョン数) - 昇格後の管理: レプリカ昇格後、新しいプライマリへのローテーション管理が必要
実装例
# 1. マルチリージョンキーを作成
aws kms create-key \
--region us-east-1 \
--multi-region true \
--description "Multi-region key for global encryption"
# 2. レプリカを作成
aws kms replicate-key \
--key-id arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd \
--replica-region ap-northeast-1 \
--description "Replica in Tokyo"
# 3. 災害時:レプリカをプライマリに昇格
aws kms update-primary-region \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/mrk-1234abcd \
--primary-region ap-northeast-1
主要ユースケース
初心者向けメモ: KMS は「暗号化」というと広く見えますが、実は 「保存時暗号化(at-rest)」 の最適なツールです。AWS サービスと深く統合されているため、数クリックで有効化できます。
1. Amazon S3 Bucket の暗号化
最も一般的なユースケース。S3 に保存されたすべてのオブジェクトを KMS CMK で暗号化。
# KMS CMK を使用して S3 bucket を暗号化
aws s3api put-bucket-encryption \
--bucket my-secure-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd"
},
"BucketKeyEnabled": true
}
]
}'
✅ メリット:
- データは保存時に自動暗号化
- KMS キーポリシーで誰がアクセスできるか制御
- CloudTrail で完全監査
- BucketKey 有効化で 99% API 呼び出し削減
❌ デメリット:
- API 呼び出し料金($0.03/10k)
- キーポリシー管理が必要
2. Amazon EBS Volume の暗号化
ストレージレベルの透過的暗号化。EC2 インスタンスのボリュームを自動暗号化。
# KMS CMK を使用して EBS ボリュームを暗号化
aws ec2 create-volume \
--availability-zone ap-northeast-1a \
--size 100 \
--encrypted \
--kms-key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
✅ メリット:
- I/O パフォーマンスへの影響なし
- スナップショットも暗号化
- EC2 API で透過的に処理
❌ デメリット:
- キーポリシーで EC2 サービスロールへのアクセス許可が必要
3. Amazon RDS Database の暗号化
DB インスタンス全体を暗号化。バックアップ・スナップショットも含む。
# KMS CMK で暗号化された RDS インスタンス
aws rds create-db-instance \
--db-instance-identifier mydb \
--db-instance-class db.t4g.micro \
--engine mysql \
--kms-key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--storage-encrypted
✅ 用途:
- クレジットカード、個人情報等を暗号化
- スナップショット共有時に鍵を明示的に付与
4. AWS Secrets Manager での秘密暗号化
API キー、パスワード、DB 認証情報の暗号化保管。
# Secrets Manager シークレットを KMS CMK で暗号化
aws secretsmanager create-secret \
--name prod/db/password \
--secret-string '{"username":"admin","password":"secret123"}' \
--kms-key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
✅ 特性:
- 自動的に Grant を作成(Lambda がシークレット読み込み可能)
- 定期的なローテーション対応
5. Lambda 環境変数の暗号化
環境変数(API キー等)を暗号化。
# Lambda 環境変数を KMS CMK で暗号化
aws lambda update-function-configuration \
--function-name myfunction \
--kms-key-arn arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--environment '{
"Variables": {
"DB_PASSWORD": "encrypted-value"
}
}'
✅ メリット:
- ソースコードに秘密が露出しない
- CloudTrail で環境変数アクセスを監査
6. DynamoDB テーブルの暗号化
テーブル全体・グローバルインデックスを暗号化。
# DynamoDB テーブルを KMS CMK で暗号化
aws dynamodb create-table \
--table-name Users \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
7. CloudWatch Logs の暗号化
ログストリームを暗号化。
# CloudWatch Logs グループを KMS CMK で暗号化
aws logs associate-kms-key \
--log-group-name /aws/lambda/myfunction \
--kms-key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
8. Application で エンベロープ暗号化を実装
AWS Encryption SDK を使用。大容量ファイルを効率的に暗号化。
import aws_encryption_sdk
kms_key_id = "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd"
kms_client = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[kms_key_id])
plaintext = b"This is sensitive data"
encrypted, encription_context = kms_client.encrypt(plaintext)
# encrypted を保存、encryption_context も保存
decrypted = kms_client.decrypt(encrypted)
9. マルチテナント SaaS での顧客データ分離
テナントごとに異なる KMS キーを割当。
# Tenant A(ユーザー ID = 100)
tenant_a_key = "arn:aws:kms:ap-northeast-1:111122223333:key/tenant-a"
# Tenant B(ユーザー ID = 200)
tenant_b_key = "arn:aws:kms:ap-northeast-1:111122223333:key/tenant-b"
# テナント A のデータを暗号化
encrypted_data_a = kms_client.encrypt(
plaintext=tenant_a_data,
key_id=tenant_a_key
)
# テナント B はテナント A キーでの復号が不可(IAM ポリシーで制限)
10. Cross-Account 暗号化(複数 AWS アカウント管理)
中央集約型アカウント(Security Account)で鍵を集中管理。
{
"Sid": "Allow cross-account access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::222233334444:role/DataProcessingRole"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey"
],
"Resource": "*"
}
11. データ署名・検証(Digital Signature)
KMS RSA キーで署名。ドキュメント改ざん検出。
# ドキュメントに署名
aws kms sign \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--message fileb://document.txt \
--signing-algorithm RSASSA_PSS_SHA_256 \
--output text \
--query Signature > document.sig
# 署名を検証
aws kms verify \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--message fileb://document.txt \
--signature fileb://document.sig \
--signing-algorithm RSASSA_PSS_SHA_256
12. JWT トークン署名(HMAC)
HMAC-256 キーで JWT 署名。
import hmac
import hashlib
import json
import base64
# HMAC キーで署名
def create_jwt(payload, kms_key_id):
header = {"alg": "HS256", "typ": "JWT"}
# payload をエンコード
encoded_header = base64.urlsafe_b64encode(json.dumps(header).encode()).decode()
encoded_payload = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode()
# KMS で HMAC を生成
message = f"{encoded_header}.{encoded_payload}".encode()
signature = kms_client.generate_mac(
KeyId=kms_key_id,
Message=message,
MacAlgorithm='HMAC_SHA_256'
)
return f"{encoded_header}.{encoded_payload}.{base64.urlsafe_b64encode(signature).decode()}"
エンベロープ暗号化
初心者向けメモ: エンベロープ暗号化は「手紙を複数の封筒で段階的に封じる」イメージです。
- 第 1 段階: データを普通の鍵(DEK)で暗号化
- 第 2 段階: その鍵をマスター鍵(CMK)で暗号化
- 保存時: 暗号化データ + 暗号化済みの鍵を一緒に保存
- 復号時: まず CMK で鍵を復号し、その鍵でデータを復号
メリット
| メリット | 説明 |
|---|---|
| パフォーマンス | DEK は高速で大量データ暗号化。CMK は少数キー呼び出しのみ |
| スケーラビリティ | 大容量ファイル(GB・TB)を効率的に暗号化可能 |
| セキュリティ | CMK のマテリアルは KMS に留まる。DEK はアプリケーション側で暗号化・復号 |
| キーローテーション | キーメタデータで管理。既存データの再暗号化不要 |
フロー図
graph TD
subgraph Encryption["暗号化フロー"]
E1["1. KMS GenerateDataKey"]
E2["KMS が返す:<br/>- プレーンテキスト DEK<br/>- 暗号化済み DEK"]
E3["2. プレーンテキスト DEK<br/>でデータを AES-256 で暗号化"]
E4["3. プレーンテキスト DEK<br/>をメモリから削除"]
E5["4. 暗号化データ<br/>+ 暗号化済み DEK<br/>を S3 に保存"]
E1 --> E2
E2 --> E3
E3 --> E4
E4 --> E5
end
subgraph Decryption["復号フロー"]
D1["1. S3 から<br/>暗号化済み DEK を取得"]
D2["2. KMS Decrypt API<br/>暗号化済み DEK を送付"]
D3["KMS が返す:<br/>プレーンテキスト DEK"]
D4["3. DEK で暗号化データ<br/>を AES-256 で復号"]
D5["4. プレーンテキスト DEK<br/>をメモリから削除"]
D1 --> D2
D2 --> D3
D3 --> D4
D4 --> D5
end
Encryption -->|暗号化| Decryption
実装例(AWS Encryption SDK)
import aws_encryption_sdk
from aws_encryption_sdk import KMSMasterKeyProvider
# KMS CMK ID
key_id = "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd"
# KMS マスターキープロバイダーを初期化
kms_provider = KMSMasterKeyProvider(key_ids=[key_id])
# データを暗号化(エンベロープ暗号化自動実行)
plaintext = b"Sensitive customer data"
ciphertext, encription_context = kms_provider.encrypt(plaintext)
# 暗号化済みデータ + 暗号化済み DEK を S3 に保存
s3_client.put_object(
Bucket='my-bucket',
Key='encrypted-data.bin',
Body=ciphertext
)
# 復号
stored_ciphertext = s3_client.get_object(
Bucket='my-bucket',
Key='encrypted-data.bin'
)['Body'].read()
decrypted = kms_provider.decrypt(stored_ciphertext)[0]
print(decrypted) # b"Sensitive customer data"
Data Key の使い方
Data Encryption Key(DEK) は、エンベロープ暗号化で実際にデータを暗号化する鍵です。
GenerateDataKey
プレーンテキスト DEK + 暗号化済み DEK を同時取得。
aws kms generate-data-key \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--key-spec AES_256
レスポンス:
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd",
"Plaintext": "base64-encoded-plaintext-dek",
"CiphertextBlob": "base64-encoded-encrypted-dek"
}
✅ 用途:
- データ暗号化時に使用(プレーンテキスト DEK)
- 暗号化データと共に保存(暗号化済み DEK)
GenerateDataKeyWithoutPlaintext
暗号化済み DEK のみを取得。プレーンテキストは不要な場合。
aws kms generate-data-key-without-plaintext \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--key-spec AES_256
✅ 用途:
- ユーザーがデータを後で復号する場合
- 暗号化済み DEK のみ保存(プレーンテキストは不要)
Decrypt
暗号化済み DEK を復号し、プレーンテキスト DEK を取得。
aws kms decrypt \
--ciphertext-blob fileb://encrypted-dek.bin \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
レスポンス:
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd",
"Plaintext": "base64-encoded-plaintext-dek"
}
✅ セキュリティ:
- KMS が暗号化・復号処理を担当
- プレーンテキスト DEK は復号呼び出し直後のみメモリに存在
- CloudTrail ですべての復号操作を記録
暗号化操作
Encrypt
4 KB 以下の小さいデータを直接 CMK で暗号化。
aws kms encrypt \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--plaintext fileb://secret.txt
✅ 用途:
- API キー、パスワード等の小規模データ
- Secrets Manager での秘密管理
❌ デメリット:
- CMK API 呼び出し料金が発生
- 大容量データには不向き
Decrypt
KMS で暗号化されたデータを復号。
aws kms decrypt \
--ciphertext-blob fileb://encrypted-secret.bin
✅ 特性:
- キーポリシーで復号操作を制御
- CloudTrail で誰がいつ何を復号したか記録
ReEncrypt
別の CMK で再暗号化。キーの切り替え時に便利。
# Old Key → New Key へデータの暗号化を切り替え
aws kms re-encrypt \
--ciphertext-blob fileb://data-encrypted-with-old-key.bin \
--source-key-id arn:aws:kms:ap-northeast-1:111122223333:key/old-key \
--destination-key-id arn:aws:kms:ap-northeast-1:111122223333:key/new-key
✅ メリット:
- 復号→再暗号化を 1 ステップで実行(セキュリティ向上)
- 大容量データの場合エンベロープ暗号化で ReEncrypt
Sign
KMS 非対称キーでデータに署名。
aws kms sign \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--message fileb://document.txt \
--signing-algorithm RSASSA_PSS_SHA_256
✅ 用途:
- デジタル署名
- JWT トークン署名
- データ完全性証明
Verify
署名を検証。
aws kms verify \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--message fileb://document.txt \
--signature fileb://document.sig \
--signing-algorithm RSASSA_PSS_SHA_256
GenerateMAC
HMAC キーでメッセージ認証コード(MAC)を生成。
aws kms generate-mac \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/hmac-key \
--message fileb://data.bin \
--mac-algorithm HMAC_SHA_256
VerifyMAC
生成された MAC を検証。
aws kms verify-mac \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/hmac-key \
--message fileb://data.bin \
--mac fileb://generated-mac.bin \
--mac-algorithm HMAC_SHA_256
Key Policy
初心者向けメモ: キーポリシーは KMS キーのアクセス制御リスト(ACL)です。IAM ポリシーだけでは不十分で、キーポリシーでも明示的に Allow が必要です。
キーポリシーの構造
{
"Sid": "一意の識別子",
"Effect": "Allow or Deny",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/MyRole"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com"
}
}
}
必須ステートメント
キーポリシーには必ず以下を含める:
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
}
✅ 理由:
- Account Root ユーザーに全権限を付与
- ロックアウト防止(AWS サポートでも復旧不可)
ロール分離パターン
管理者(Admin)と利用者(User)を分離:
[
{
"Sid": "Enable Root",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/KeyAdminRole"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Delete*",
"kms:UpdateKey*",
"kms:EnableKeyRotation",
"kms:DisableKeyRotation",
"kms:GetPublicKey",
"kms:ImportKeyMaterial",
"kms:PutKeyPolicy"
],
"Resource": "*"
},
{
"Sid": "Allow Key Usage Only",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/AppRole"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "*"
}
]
サービスロール用キーポリシー
AWS サービス(S3、EBS 等)がキーを使用できるようにする:
{
"Sid": "Allow EBS to use the key",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey"
],
"Resource": "*"
}
条件付きアクセス制御
特定の条件下でのみキー使用を許可:
{
"Sid": "Allow Decrypt only via S3",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/DataAnalystRole"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.ap-northeast-1.amazonaws.com"
}
}
}
✅ 条件の例:
| 条件 | 値 |
|---|---|
kms:ViaService |
s3.*.amazonaws.com ← S3 経由のみ |
kms:EncryptionContext:Department |
Finance ← 特定の部門のみ |
aws:SourceIp |
10.0.0.0/8 ← 特定 IP 範囲のみ |
aws:PrincipalOrgID |
o-1234567890 ← 同一組織内のみ |
キーポリシー管理(IaC)
Terraform で管理:
resource "aws_kms_key" "example" {
description = "KMS key for S3 encryption"
deletion_window_in_days = 10
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable Root"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::111122223333:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow S3"
Effect = "Allow"
Principal = {
Service = "s3.amazonaws.com"
}
Action = ["kms:Decrypt", "kms:GenerateDataKey"]
Resource = "*"
}
]
})
}
Grants
初心者向けメモ: Grant は「キーポリシーを変更せずに、一時的に特定のプリンシパルに権限を付与する仕組み」です。
用途
| シーン | 従来の方法 | Grant での方法 |
|---|---|---|
| Lambda が Secrets Manager を読む | キーポリシーを修正 | Grant を自動作成 |
| 一時的にアクセス権を付与 | キーポリシーを追加 → 削除 | Grant を作成 → 削除 |
| 監査可能な権限委任 | キーポリシー履歴不確実 | Grant は CloudTrail に記録 |
Grant の仕組み
# Grant を作成
aws kms create-grant \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--grantee-principal arn:aws:iam::111122223333:role/LambdaRole \
--operations Decrypt GenerateDataKey \
--name my-grant
レスポンス:
{
"GrantId": "abc123def456...",
"GrantToken": "AQpAM2RhZ..."
}
Grant Token
即座に権限を有効にする(ポリシーの遅延反映を回避):
# Lambda で Secrets Manager を読む
import boto3
sm_client = boto3.client('secretsmanager')
# Grant Token を使用
response = sm_client.get_secret_value(
SecretId='prod/db/password',
GrantTokens=['AQpAM2RhZ...']
)
✅ メリット:
- ポリシー変更の遅延反映(数秒)を回避
- 権限がすぐに有効
Grant 管理
# 有効な Grant を一覧
aws kms list-grants \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
# Grant を削除
aws kms retire-grant \
--grant-id abc123def456...
Key Rotation
初心者向けメモ: キーローテーションは「古い鍵マテリアルを廃棄し、新しいマテリアルに切り替える」ことですが、既存データの再暗号化は不要 です。KMS が背後で管理します。
自動キーローテーション
CMK を対象に、AWS が 1 年ごとに自動でローテーション。
# 自動ローテーション有効化
aws kms enable-key-rotation \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
# ローテーション状態を確認
aws kms get-key-rotation-status \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
レスポンス:
{
"KeyId": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd",
"KeyRotationEnabled": true
}
✅ メリット:
- 自動実行(AWS が管理)
- 既存データも復号可能(古いマテリアルを保持)
- コンプライアンス要件(FIPS 140-2)を満たす
❌ デメリット:
- ローテーション頻度を制御不可(固定 1 年)
- AWS Managed Key では自動だが Admin が有効/無効を制御不可
オンデマンドローテーション
手動で任意のタイミングでローテーション。
# ローテーション実行
aws kms rotate-key-on-demand \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
✅ 用途:
- セキュリティ侵害時の緊急ローテーション
- カスタムローテーション周期を実装
External Key Material でのローテーション
BYOK の場合、手動ローテーション:
# 1. 新しいキーマテリアルを外部 HSM で生成
# 2. KMS に新しいマテリアルをインポート
aws kms import-key-material \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/external-key \
--encrypted-key-material fileb://encrypted-new-material.bin \
--import-token fileb://import-token.bin
# 3. 古いマテリアルを削除
aws kms delete-imported-key-material \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/external-key
ローテーション後の検証
# キーのバージョン情報を確認
aws kms list-key-versions \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
CloudHSM 連携
初心者向けメモ: CloudHSM 統合(External Key Store)は「AWS KMS の便利さ」と「CloudHSM の最高度セキュリティ」を組み合わせたハイブリッドアプローチです。
External Key Store(XKS)の位置づけ
KMS Standard:
共有 HSM → マルチテナント → 標準セキュリティ → 低コスト
CloudHSM:
物理 HSM を専有 → FIPS 140-2 Level 3 → 最高度セキュリティ → 高コスト
KMS XKS(CloudHSM 連携):
CloudHSM の HSM を外部キーストアとして KMS 経由でアクセス
→ KMS の API 整合性 + CloudHSM の Level 3 準拠
アーキテクチャ
アプリケーション
↓
KMS API(Encrypt/Decrypt)
↓
KMS XKS サービス
↓ AWS プライベートネットワーク
CloudHSM クラスタ
↓
物理 HSM モジュール(FIPS 140-2 Level 3)
↓
鍵マテリアル(物理的に分散保存)
CloudHSM キーストア設定
# 1. CloudHSM クラスタを作成
aws cloudhsm create-cluster \
--hsm-type hsm2 \
--availability-zone ap-northeast-1a
# 2. HSM を追加
aws cloudhsm create-hsm \
--cluster-id cluster-xxxxx \
--availability-zone ap-northeast-1a
# 3. CloudHSM キーストアを作成
aws kms create-custom-key-store \
--custom-key-store-name "cloudhsm-keystore" \
--cloud-hsm-cluster-id cluster-xxxxx \
--key-store-password <password>
# 4. キーストアを接続
aws kms connect-custom-key-store \
--custom-key-store-id cks-xxxxx
# 5. キーストア内にキーを作成
aws kms create-key \
--key-store-id cks-xxxxx \
--key-type SYMMETRIC_DEFAULT
✅ メリット:
- FIPS 140-2 Level 3 準拠
- 物理 HSM での専有運用
- ハードウェアセキュリティモジュールの最高度保護
❌ デメリット:
- CloudHSM コスト:$1.45/時間 + 初期投資
- 設定・管理の複雑性
- キーマテリアルが CloudHSM に完全に依存(AWS では管理不可)
セキュリティ・監査
FIPS 140-2 準拠
| 基準 | KMS Standard | CloudHSM |
|---|---|---|
| 準拠レベル | FIPS 140-2 Level 3 | FIPS 140-2 Level 3 |
| 物理セキュリティ | 共有 HSM 内で論理的分離 | 物理 HSM を専有 |
| 監査 | AWS 監査対象 | カスタマー監査可能 |
暗号化アルゴリズム
| 操作 | アルゴリズム |
|---|---|
| 対称暗号化 | AES-256 (GCM モード) |
| 非対称(RSA) | RSASSA-PSS、RSASSA-PKCS1-v1_5 |
| 非対称(ECC) | ECDSA |
| HMAC | SHA-256、SHA-384、SHA-512 |
アクセス制御のレイヤー
IAM ポリシー + キーポリシー + リソースポリシー
1. IAM ポリシー:「このロールが kms:Decrypt を実行できるか」
2. キーポリシー:「このキーで kms:Decrypt を実行できるか」
3. リソースポリシー:「VPC、IP アドレスなどで追加制限」
すべての条件が Allow である必要がある
暗号コンテキスト
追加の認証データ(AAD)として用途を限定:
import boto3
kms_client = boto3.client('kms')
# 暗号化時に暗号コンテキストを指定
ciphertext = kms_client.encrypt(
KeyId='arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd',
Plaintext=b'secret-data',
EncryptionContext={
'Department': 'Finance',
'DataType': 'PayrollData'
}
)
# 復号時も同じ暗号コンテキストが必要
plaintext = kms_client.decrypt(
CiphertextBlob=ciphertext['CiphertextBlob'],
EncryptionContext={
'Department': 'Finance',
'DataType': 'PayrollData'
}
)
✅ メリット:
- 暗号化データが別用途で使用されることを防止
- 用途別の監査が容易
モニタリング
CloudTrail 統合
すべての KMS API 呼び出しを記録:
{
"eventVersion": "1.07",
"eventTime": "2026-04-26T10:30:00Z",
"eventSource": "kms.amazonaws.com",
"eventName": "Decrypt",
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "192.0.2.1",
"userAgent": "aws-cli/2.13.0",
"requestParameters": {
"keyId": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd"
},
"responseElements": null,
"additionalEventData": {
"encryptionContext": {
"Department": "Finance"
}
},
"requestId": "12345678-1234-1234-1234-123456789012",
"eventID": "87654321-4321-4321-4321-210987654321",
"eventName": "Decrypt",
"eventType": "AwsApiCall"
}
CloudWatch Metrics
KMS メトリクスを CloudWatch に送信:
# キーの使用状況メトリクス
aws cloudwatch get-metric-statistics \
--namespace AWS/KMS \
--metric-name UserErrorCount \
--dimensions Name=KeyId,Value=arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd \
--start-time 2026-04-25T10:00:00Z \
--end-time 2026-04-26T10:00:00Z \
--period 3600 \
--statistics Sum
| メトリクス | 説明 |
|---|---|
| UserErrorCount | ユーザーエラー(無効なリクエスト等)の数 |
| ThrottledCount | スロットル(レート制限)されたリクエスト数 |
| RequestCount | 総リクエスト数 |
Grafana での可視化
DataSource: CloudWatch
Query: aws_kms_user_error_count
{KeyId: "1234abcd..."}
Panel: Time Series Graph
Legend: KeyId
Y-axis: Count
Alert: > 5 errors/hour
AWS X-Ray との統合
分散トレースで KMS API 呼び出しを追跡:
from aws_xray_sdk.core import xray_recorder
import boto3
kms_client = boto3.client('kms')
xray_recorder.configure(service='KMS')
@xray_recorder.capture('decrypt_secret')
def decrypt_secret():
response = kms_client.decrypt(
CiphertextBlob=b'encrypted-data'
)
return response
コスト
料金体系
| 項目 | 料金 |
|---|---|
| CMK 保管料 | $1/月/キー(AWS Managed も同じ) |
| API 呼び出し | $0.03/10,000 リクエスト(最初の 20,000 は無料) |
| マルチリージョンレプリカ | プライマリ 1/月 + レプリカ 1/月 × リージョン数 |
| CloudHSM キーストア | CloudHSM コスト + KMS |
コスト削減テクニック
1. BucketKey の有効化(S3)
API 呼び出しを 99% 削減:
# S3 bucket に BucketKey を有効化
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd"
},
"BucketKeyEnabled": true
}
]
}'
効果:
- 通常:オブジェクト数 × GenerateDataKey API 呼び出し
- BucketKey 有効時:データキーを S3 が 15 分間キャッシュ → API 呼び出し大幅削減
2. AWS Managed Key を活用(ポリシー制御不要な場合)
AWS Owned Key(無料)で十分な場合は使用。
# デフォルト S3 暗号化(AWS Owned Key)
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256" # AWS Owned Key(無料)
}
}
]
}'
❌ デメリット:
- ポリシー制御不可
- CloudTrail 記録不確実
3. API 呼び出しをバッチ化
Batch 操作で複数リクエストを効率化:
import boto3
kms_client = boto3.client('kms')
# 複数の Decrypt を同時実行(並列化)
import concurrent.futures
ciphertexts = [...]
def decrypt_one(ct):
return kms_client.decrypt(CiphertextBlob=ct)
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(decrypt_one, ciphertexts)
コスト計算例
シナリオ:S3 に 1 日 100 万オブジェクトを保存、KMS CMK で暗号化
BucketKey 有効化なし:
GenerateDataKey: 100 万リクエスト/日 ÷ 10,000 × $0.03 = $3/日
CMK 保管: $1/月 = $0.033/日
月額: 約 $90 + $1 = $91
BucketKey 有効化あり:
GenerateDataKey: 100 万リクエスト → S3 キャッシュで 1,000 リクエスト/日
月額: 約 $0.09 + $1 = $1.09 / 月
削減額:$89.91/月(99% 削減)
他の類似ツールとの比較
| ツール | 管理方式 | コスト | セキュリティ | 用途 |
|---|---|---|---|---|
| AWS KMS | フルマネージド | 安い($1 + API) | FIPS L3(共有 HSM) | AWS 統合メイン |
| AWS CloudHSM | カスタマーコントロール | 高い($1.45/h) | FIPS L3(専有 HSM) | コンプライアンス重視 |
| HashiCorp Vault | セルフホスト | ソフト無料 + インフラ | カスタマイズ可能 | オンプレ / ハイブリッド |
| Azure Key Vault | フルマネージド | 低い($0.03 + API) | FIPS L2/L3 | Azure 統合メイン |
| GCP KMS | フルマネージド | 低い($0.06 + API) | FIPS L3 準拠 | GCP 統合メイン |
| Thales CipherTrust | エンタープライズ | 非常に高い | FIPS L3 + カスタム | 大規模エンタープライズ |
比較表(詳細)
| カテゴリ | AWS KMS | Azure KV | GCP KMS | Vault | CloudHSM |
|---|---|---|---|---|---|
| AWS 統合度 | ✅✅✅ | ❌ | ❌ | ⚠️ | ✅✅✅ |
| Azure 統合度 | ❌ | ✅✅✅ | ❌ | ⚠️ | ❌ |
| GCP 統合度 | ❌ | ❌ | ✅✅✅ | ⚠️ | ❌ |
| マルチクラウド | ❌ | ❌ | ❌ | ✅✅✅ | ❌ |
| オンプレ対応 | ❌ | ❌ | ❌ | ✅✅✅ | ✅ |
| FIPS Level 3 | ✅ | ⚠️ Level 2 | ✅ | ⚠️ | ✅✅✅ |
| 自動ローテーション | ✅ | ✅ | ✅ | ❌ | ❌ |
| コスト効率 | ✅ | ✅ | ✅ | ✅ | ❌ |
選択フロー
Q1: AWS のみ使用?
├─ YES → Q2
└─ NO(マルチクラウド)→ HashiCorp Vault
Q2: FIPS 140-2 Level 3 が必須?
├─ YES(物理 HSM)→ CloudHSM
└─ NO → Q3
Q3: ポリシー制御・監査が必要?
├─ YES → KMS CMK
└─ NO(デフォルト暗号化のみ)→ AWS Managed Key
クライアントとエコシステム
AWS Encryption SDK
言語別エンベロープ暗号化クライアント:
# Python
import aws_encryption_sdk
kms_provider = aws_encryption_sdk.KMSMasterKeyProvider(
key_ids=['arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd']
)
ciphertext, ctx = kms_provider.encrypt(b'plaintext')
// JavaScript
const {KmsKeyringNode} = require('@aws-sdk/client-kms');
const keyring = new KmsKeyringNode({keyIds: ['arn:aws:...']});
const {result} = await encrypt(keyring, Buffer.from('plaintext'));
// Go
import "github.com/aws/aws-encryption-sdk-go"
kmsProvider := aws_sdk_go.NewKMSProvider(cfg, []string{"arn:aws:kms:..."})
ciphertext, _ := kmsProvider.Encrypt(context.Background(), []byte("plaintext"))
AWS Database Encryption SDK
DB クエリの暗号化:
from aws_database_encryption_sdk.structured_encryption import (
StructuredEncryptionClient
)
db_client = StructuredEncryptionClient()
encrypted_item = db_client.encrypt_item(
item={'email': 'user@example.com', 'ssn': '123-45-6789'},
schema={'email': PlaintextSchema, 'ssn': EncryptedSchema},
kms_client=kms_client
)
SDK Integration
| SDK | 対応状況 | URL |
|---|---|---|
| boto3(Python) | ✅ ネイティブ | https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms.html |
| AWS SDK for JavaScript | ✅ ネイティブ | https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/ |
| AWS SDK for Java | ✅ ネイティブ | https://docs.aws.amazon.com/sdk-for-java/latest/ |
| AWS CLI | ✅ ネイティブ | https://docs.aws.amazon.com/cli/latest/reference/kms/ |
ベストプラクティス
1. Least Privilege(最小権限の原則)
必要最小限の権限のみをキーポリシーで付与:
{
"Sid": "AllowAppDecrypt",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:role/AppRole"},
"Action": ["kms:Decrypt"], ← Decrypt のみ、他の操作は許可しない
"Resource": "*"
}
❌ アンチパターン:
{
"Action": "kms:*", ← すべてのアクション許可
"Resource": "*"
}
2. 定期的なキーローテーション
自動ローテーションを有効化(CMK):
aws kms enable-key-rotation \
--key-id arn:aws:kms:ap-northeast-1:111122223333:key/1234abcd
✅ 効果:
- セキュリティ侵害時の被害最小化
- コンプライアンス要件(FIPS)を満たす
3. CloudTrail ロギング有効化
すべての KMS API 呼び出しを監査:
# CloudTrail を有効化(KMS も含まれる)
aws cloudtrail create-trail --name kms-audit --s3-bucket-name my-audit-bucket
aws cloudtrail start-logging --trail-name kms-audit
✅ 監査項目:
- 誰がいつどのキーで何を実行したか
- 失敗したリクエスト
- キーのポリシー変更履歴
4. キーポリシーの Root 保護
必ず Account Root に全権限を付与(ロックアウト防止):
{
"Sid": "Enable Root",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"
}
❌ やってはいけない:
// Root を削除 → ロックアウト(AWS サポートでも復旧不可)
5. 複数テナント環境での鍵分離
テナントごとに異なる KMS キーを割当:
# Tenant A のデータ
tenant_a_key = "arn:aws:kms:ap-northeast-1:111122223333:key/tenant-a-key"
tenant_a_encrypted = kms_client.encrypt(
KeyId=tenant_a_key,
Plaintext=tenant_a_data
)
# Tenant B のデータ
tenant_b_key = "arn:aws:kms:ap-northeast-1:111122223333:key/tenant-b-key"
tenant_b_encrypted = kms_client.encrypt(
KeyId=tenant_b_key,
Plaintext=tenant_b_data
)
# IAM ポリシーで
# - Tenant A ロール:tenant-a-key のみアクセス可
# - Tenant B ロール:tenant-b-key のみアクセス可
6. 環境別のキー分離
本番・ステージング・開発で異なるキーを使用:
ENV = 'production' # or 'staging', 'development'
KMS_KEYS = {
'production': 'arn:aws:kms:ap-northeast-1:111122223333:key/prod-key',
'staging': 'arn:aws:kms:ap-northeast-1:111122223333:key/staging-key',
'development': 'arn:aws:kms:ap-northeast-1:111122223333:key/dev-key'
}
kms_key_id = KMS_KEYS[ENV]
✅ メリット:
- 開発者の誤操作から本番データを保護
- 環境間の権限分離
7. BucketKey の有効化(S3 での費用削減)
API 呼び出しを 99% 削減:
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:..."
},
"BucketKeyEnabled": true
}]
}'
8. エンベロープ暗号化を使用
大容量データは GenerateDataKey を使用(Encrypt API は避ける):
# 推奨:エンベロープ暗号化
response = kms_client.generate_data_key(
KeyId=kms_key_id,
KeySpec='AES_256'
)
plaintext_dek = response['Plaintext']
encrypted_dek = response['CiphertextBlob']
# データを DEK で暗号化
encrypted_data = encrypt_with_aes_256(plaintext_dek, data)
# DEK をメモリから削除
del plaintext_dek
# encrypted_data + encrypted_dek を保存
9. 暗号コンテキスト を活用
用途別に暗号化を制限:
# 暗号化
ciphertext = kms_client.encrypt(
KeyId=kms_key_id,
Plaintext=sensitive_data,
EncryptionContext={'UserId': '12345', 'DataType': 'PII'}
)
# 復号(同じ暗号コンテキストが必須)
plaintext = kms_client.decrypt(
CiphertextBlob=ciphertext['CiphertextBlob'],
EncryptionContext={'UserId': '12345', 'DataType': 'PII'}
)
10. キーポリシーをコード管理
IaC(Terraform / CloudFormation)で管理:
# Terraform
resource "aws_kms_key" "example" {
description = "KMS key for app"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable Root"
Effect = "Allow"
Principal = {AWS = "arn:aws:iam::111122223333:root"}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow App"
Effect = "Allow"
Principal = {AWS = "arn:aws:iam::111122223333:role/AppRole"}
Action = ["kms:Decrypt", "kms:GenerateDataKey"]
Resource = "*"
}
]
})
}
トラブルシューティング
Q1: キーポリシーでロックアウトされた
A: AWS サポートに連絡してもロック解除不可。削除待機期間を待つ必要があります。
予防策:
{
"Sid": "Enable Root",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"
}
Q2: Decrypt API が “InvalidKeyId” エラー
A: 以下をチェック
- ✅ キーが存在するか:
aws kms describe-key --key-id <key-id> - ✅ キーポリシーでアクセスが許可されているか
- ✅ IAM ポリシーで
kms:Decryptが許可されているか - ✅ リージョンが正しいか
Q3: API 呼び出しがスロットル(レート制限)される
A: KMS には API のレート制限があります。
| 操作 | 制限 |
|---|---|
| GenerateDataKey | 10,000 rps |
| Encrypt | 10,000 rps |
| Decrypt | 10,000 rps |
| Others | 5,000 rps |
対策:
- BucketKey を有効化(S3)
- エンベロープ暗号化を使用
- AWS Support に制限緩和をリクエスト
Q4: 古いキーマテリアルで暗号化されたデータが復号できない
A: KMS キーローテーション後も古いマテリアルは保持されるため、通常は復号可能です。
# 復号可能なキーマテリアルを確認
aws kms list-key-versions --key-id <key-id>
Q5: CloudHSM 連携時に接続エラー
A: CloudHSM クラスタの接続状態を確認
aws kms describe-custom-key-stores --custom-key-store-id cks-xxxxx
# Status が "CONNECTED" であることを確認
2025-2026 最新動向
1. Post-Quantum Cryptography(量子耐性暗号)
AWS は PQC 対応を検討中。量子コンピュータ登場に備えた暗号への移行。
- NIST 標準化: FIPS 203(ML-KEM)、FIPS 204(ML-DSA)の採用予定
- AWS ロードマップ: 2026-2027 年に KMS で PQC サポート予定
2. External Key Store(XKS)の拡張
CloudHSM 統合を進化させ、オンプレミス HSM との直接連携を強化。
- 複数ベンダー対応: Thales、Yubico 等のサードパーティ HSM 対応
- 低レイテンシアクセス: AWS Outposts での XKS サポート
3. AI 駆動鍵管理
機械学習による異常検知・キーローテーション推奨。
- 異常検知: 通常と異なるアクセスパターンを自動検出
- ポリシー提案: キーポリシーの最小権限化を AI が支援
- キーローテーション最適化: セキュリティ と パフォーマンスのバランスを自動計算
4. Cross-Account Multi-Region Keys
複数アカウント × 複数リージョンで統一的に鍵を管理。
Central Security Account
↓
Multi-Region Multi-Account Key
├─ Prod Account(us-east-1)
├─ Prod Account(ap-northeast-1)
├─ Staging Account(us-east-1)
└─ Dev Account(us-east-1)
5. Grafana / Prometheus 統合の深化
KMS メトリクスをネイティブに Prometheus / Grafana で可視化。
# Prometheus クエリ例
aws_kms_user_error_count{KeyId="1234abcd"}
# Grafana ダッシュボード
- KMS API 呼び出し率
- スロットル率
- キーローテーション履歴
- アクセス制御違反検出
6. 統合セキュリティスコアリング
AWS Security Hub と統合した KMS セキュリティスコア。
- ✅ キーローテーション実施状況
- ✅ キーポリシーの最小権限度
- ✅ CloudTrail ロギング有効化
- ✅ 未使用キーの自動削除提案
学習リソース
公式ドキュメント
| リソース | URL |
|---|---|
| KMS 開発者ガイド | https://docs.aws.amazon.com/kms/latest/developerguide/ |
| KMS API リファレンス | https://docs.aws.amazon.com/kms/latest/APIReference/ |
| AWS Encryption SDK | https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/ |
| CloudHSM ユーザーガイド | https://docs.aws.amazon.com/cloudhsm/latest/userguide/ |
| AWS KMS ベストプラクティス | https://docs.aws.amazon.com/kms/latest/developerguide/best-practices.html |
学習パス
初級(1-2 週間)
- KMS の概念理解(対称鍵・非対称鍵・HMAC)
- 基本的なエンベロープ暗号化
- S3 / EBS での暗号化有効化
- CloudTrail でのログ確認
中級(2-4 週間)
- キーポリシーの設計・実装
- マルチリージョンキー
- Grants の活用
- AWS Encryption SDK での実装
上級(4 週間以上)
- CloudHSM 連携(XKS)
- マルチアカウント・マルチテナント設計
- セキュリティ監査・コンプライアンス設計
- パフォーマンス最適化(BucketKey 等)
実装例・活用シーン
シーン 1:マルチテナント SaaS での顧客データ分離
要件: 各顧客データを異なる KMS キーで暗号化、顧客間の復号不可
class TenantsDataEncryptor:
def __init__(self, kms_client):
self.kms = kms_client
self.tenant_keys = {} # キャッシュ
def encrypt_tenant_data(self, tenant_id, data):
key_id = self._get_or_create_tenant_key(tenant_id)
return self.kms.encrypt(KeyId=key_id, Plaintext=data)
def decrypt_tenant_data(self, tenant_id, ciphertext):
key_id = self.tenant_keys.get(tenant_id)
if not key_id:
raise Exception(f"Tenant {tenant_id} key not found")
return self.kms.decrypt(CiphertextBlob=ciphertext)
def _get_or_create_tenant_key(self, tenant_id):
if tenant_id not in self.tenant_keys:
# テナント用キーを作成
response = self.kms.create_key(
Description=f"Key for tenant {tenant_id}",
Tags=[{'TagKey': 'TenantId', 'TagValue': str(tenant_id)}]
)
self.tenant_keys[tenant_id] = response['KeyMetadata']['KeyId']
return self.tenant_keys[tenant_id]
シーン 2:ハイブリッド環境での暗号化キー管理
要件: オンプレミス + AWS での統一鍵管理(CloudHSM XKS 使用)
# 1. CloudHSM クラスタを構築
aws cloudhsm create-cluster \
--hsm-type hsm2 \
--availability-zone us-east-1a
# 2. KMS Custom Key Store を作成
aws kms create-custom-key-store \
--custom-key-store-name "hybrid-keystore" \
--cloud-hsm-cluster-id cluster-xxxxx \
--key-store-password <password>
# 3. キーストアで KMS キーを作成
aws kms create-key --custom-key-store-id cks-xxxxx
# 4. オンプレミスアプリから AWS KMS API 経由でアクセス
# (秘密鍵は CloudHSM で保護)
シーン 3:自動バックアップの暗号化・リストア
要件: 日次バックアップを KMS 暗号化、別リージョンへクロスリージョン復号
class BackupManager:
def __init__(self, s3, kms, backup_bucket):
self.s3 = s3
self.kms = kms
self.backup_bucket = backup_bucket
def backup_with_encryption(self, data, key_id):
# エンベロープ暗号化
dek_response = self.kms.generate_data_key(KeyId=key_id, KeySpec='AES_256')
plaintext_dek = dek_response['Plaintext']
encrypted_dek = dek_response['CiphertextBlob']
# データ暗号化
encrypted_data = self._encrypt_data(plaintext_dek, data)
# バックアップを S3 に保存
self.s3.put_object(
Bucket=self.backup_bucket,
Key=f"backup-{datetime.now().isoformat()}.enc",
Body=encrypted_data,
Metadata={
'encrypted-dek': encrypted_dek.hex(),
'kms-key-id': key_id
}
)
def restore_from_backup(self, backup_key):
# S3 からバックアップ取得
response = self.s3.get_object(Bucket=self.backup_bucket, Key=backup_key)
encrypted_data = response['Body'].read()
encrypted_dek = bytes.fromhex(response['Metadata']['encrypted-dek'])
# KMS で DEK を復号
dek_response = self.kms.decrypt(CiphertextBlob=encrypted_dek)
plaintext_dek = dek_response['Plaintext']
# データを復号
return self._decrypt_data(plaintext_dek, encrypted_data)
導入ロードマップ
Phase 1:評価・計画(1-2 週間)
- [ ] 現在のセキュリティ体制を把握
- [ ] コンプライアンス要件を整理(HIPAA、PCI-DSS 等)
- [ ] AWS KMS vs CloudHSM vs 他ツールの比較
- [ ] コスト試算
Phase 2:基盤構築(2-4 週間)
- [ ] KMS キーを作成(環境別:本番・ステージング・開発)
- [ ] キーポリシーを設計・実装
- [ ] CloudTrail ロギングを有効化
- [ ] 開発チームへのトレーニング
Phase 3:パイロット導入(4-8 週間)
- [ ] 非本番環境で KMS 暗号化を有効化(S3、EBS 等)
- [ ] 暗号化・復号パフォーマンステスト
- [ ] キーローテーション手順を確認
- [ ] 監視・アラートを設定
Phase 4:本番導入(8-12 週間)
- [ ] 本番環境で段階的に有効化
- [ ] 既存データの暗号化(ReEncrypt を検討)
- [ ] オペレーション手順を確立
- [ ] セキュリティ監査を実施
Phase 5:最適化・高度化(継続)
- [ ] キーローテーション頻度の検討
- [ ] マルチリージョン展開
- [ ] CloudHSM への移行検討(必要に応じ)
- [ ] AI / ML ベースの異常検知導入
実装チェックリスト
セキュリティ
- ✅ CMK(Customer Managed Key)を使用しているか(AWS Managed キーではなく)
- ✅ キーポリシーで Account Root に全権限があるか(ロックアウト防止)
- ✅ 最小権限の原則に従っているか(必要な操作のみ許可)
- ✅ 環境別・テナント別にキーを分離しているか
- ✅ キーローテーションが有効化されているか(CMK の場合)
監査・コンプライアンス
- ✅ CloudTrail ロギングが有効か
- ✅ CloudWatch アラートが設定されているか(異常アクセス検知)
- ✅ キーポリシー変更履歴が記録されているか
- ✅ 定期的なアクセスレビューを実施しているか
- ✅ 削除済みキーの待機期間が適切か(7-30 日)
パフォーマンス・コスト
- ✅ S3 で BucketKey が有効化されているか(API 呼び出し削減)
- ✅ エンベロープ暗号化を使用しているか(大容量データ)
- ✅ 不要なキーが削除予定になっているか
- ✅ マルチリージョンキーが必要か検討したか
- ✅ CloudHSM への移行が必要か検討したか
運用
- ✅ キーローテーション手順が文書化されているか
- ✅ 緊急時のキーローテーション手順が準備されているか
- ✅ 鍵の復旧手順が準備されているか(BYOK の場合)
- ✅ チーム内でオペレーション知識を共有しているか
- ✅ 災害復旧計画に KMS キーが含まれているか
統合
- ✅ S3 での暗号化が有効化されているか
- ✅ EBS での暗号化が有効化されているか
- ✅ RDS での暗号化が有効化されているか
- ✅ Secrets Manager での暗号化が有効化されているか
- ✅ Lambda 環境変数が暗号化されているか
まとめ
AWS KMS は、「暗号鍵の銀行」 として機能する統合鍵管理サービスです。以下の点が他ツールと異なります:
KMS を選ぶ理由
- FIPS 140-2 準拠:鍵マテリアルは HSM 内に密閉、外部に出ない
- AWS 深い統合:S3、EBS、RDS、Lambda、Secrets Manager など 100+ サービス
- エンベロープ暗号化:大容量データを効率的に暗号化
- 完全な監査:CloudTrail で全 API 呼び出しを記録
- 低コスト:$1/月 + API 呼び出し(BucketKey で 99% 削減可)
KMS 選択判断フロー
ポリシー制御が必要?
├─ YES → Customer Managed Key
└─ NO → AWS Managed Key で OK
マルチリージョン必要?
├─ YES → Multi-Region Keys
└─ NO → 単一リージョン
FIPS Level 3(物理 HSM)必須?
├─ YES → CloudHSM + XKS
└─ NO → KMS Standard
最後に
KMS は AWS セキュリティの基本。暗号化は「オプション」ではなく「必須」の時代です。今すぐ AWS KMS の導入を検討し、あなたのデータを次のレベルのセキュリティで保護してください。
参考文献
公式ドキュメント
- https://docs.aws.amazon.com/kms/latest/developerguide/
- https://docs.aws.amazon.com/kms/latest/APIReference/
- https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/
- https://docs.aws.amazon.com/cloudhsm/latest/userguide/
- https://docs.aws.amazon.com/secrets-manager/latest/userguide/
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html
ベストプラクティス
- https://docs.aws.amazon.com/kms/latest/developerguide/best-practices.html
- https://aws.amazon.com/security/best-practices/
- https://docs.aws.amazon.com/security/latest/userguide/
セキュリティ標準
- FIPS 140-2 Level 3:https://csrc.nist.gov/publications/detail/fips/140/2
- NIST ガイドライン:https://nvlpubs.nist.gov/nistpubs/
学習・トレーニング
- AWS Skill Builder KMS コース:https://skillbuilder.aws.com/
- AWS Well-Architected:https://aws.amazon.com/architecture/well-architected/
- A Cloud Guru KMS コース:https://acloudguru.com/
関連ツール比較
- HashiCorp Vault:https://www.vaultproject.io/
- Azure Key Vault:https://azure.microsoft.com/en-us/products/key-vault/
- GCP KMS:https://cloud.google.com/security/products/key-management
AWS ブログ・事例
- AWS Security Blog:https://aws.amazon.com/blogs/security/
- AWS Whitepaper on Encryption:https://d1.awsstatic.com/whitepapers/security/
2025-2026 最新参考文献
- ML-KEM Post-Quantum TLS Support in AWS KMS - 量子耐性暗号化対応
- ML-DSA Post-Quantum Signing with AWS KMS - 量子耐性署名(2026新機能)
- Post-Quantum Cryptography Roadmap - PQC移行計画
- NIST Post-Quantum Cryptography Standards - PQC標準化
- AWS KMS External Key Store (XKS) - CloudHSM統合
- Hybrid Post-Quantum Security Policies
- AWS Cryptographic SDK
最終更新:2026-04-26