目次

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 準拠、高コスト

目次

  1. 概要
  2. KMS が解決する課題
  3. 主な特徴
  4. アーキテクチャ
  5. キータイプと種類
  6. Customer Managed Key vs AWS Managed Key
  7. Multi-Region Keys
  8. 主要ユースケース
  9. エンベロープ暗号化
  10. Data Key の使い方
  11. 暗号化操作
  12. Key Policy
  13. Grants
  14. Key Rotation
  15. CloudHSM 連携
  16. セキュリティ・監査
  17. モニタリング
  18. コスト
  19. 他の類似ツールとの比較
  20. クライアントとエコシステム
  21. ベストプラクティス
  22. トラブルシューティング
  23. 2025-2026 最新動向
  24. 学習リソース
  25. 実装例・活用シーン
  26. 導入ロードマップ
  27. 実装チェックリスト
  28. まとめ
  29. 参考文献

概要

初心者向けメモ: 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 つのレイヤーで構成されます:

  1. コントロールプレーン:キーの作成・ポリシー管理(AWS コンソール)
  2. 管理プレーン:キーのメタデータ・ローテーション・ライフサイクル管理
  3. データプレーン:暗号化・復号 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. 第 1 段階: データを普通の鍵(DEK)で暗号化
  2. 第 2 段階: その鍵をマスター鍵(CMK)で暗号化
  3. 保存時: 暗号化データ + 暗号化済みの鍵を一緒に保存
  4. 復号時: まず 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 週間)

  1. KMS の概念理解(対称鍵・非対称鍵・HMAC)
  2. 基本的なエンベロープ暗号化
  3. S3 / EBS での暗号化有効化
  4. CloudTrail でのログ確認

中級(2-4 週間)

  1. キーポリシーの設計・実装
  2. マルチリージョンキー
  3. Grants の活用
  4. AWS Encryption SDK での実装

上級(4 週間以上)

  1. CloudHSM 連携(XKS)
  2. マルチアカウント・マルチテナント設計
  3. セキュリティ監査・コンプライアンス設計
  4. パフォーマンス最適化(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 を選ぶ理由

  1. FIPS 140-2 準拠:鍵マテリアルは HSM 内に密閉、外部に出ない
  2. AWS 深い統合:S3、EBS、RDS、Lambda、Secrets Manager など 100+ サービス
  3. エンベロープ暗号化:大容量データを効率的に暗号化
  4. 完全な監査:CloudTrail で全 API 呼び出しを記録
  5. 低コスト:$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 の導入を検討し、あなたのデータを次のレベルのセキュリティで保護してください。


参考文献

公式ドキュメント

ベストプラクティス

セキュリティ標準

学習・トレーニング

関連ツール比較

AWS ブログ・事例

2025-2026 最新参考文献

  1. ML-KEM Post-Quantum TLS Support in AWS KMS - 量子耐性暗号化対応
  2. ML-DSA Post-Quantum Signing with AWS KMS - 量子耐性署名(2026新機能)
  3. Post-Quantum Cryptography Roadmap - PQC移行計画
  4. NIST Post-Quantum Cryptography Standards - PQC標準化
  5. AWS KMS External Key Store (XKS) - CloudHSM統合
  6. Hybrid Post-Quantum Security Policies
  7. AWS Cryptographic SDK

最終更新:2026-04-26