SJ blog
security
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

保存時・転送時暗号化 — AWSサービス別の暗号化設計パターン

保存時暗号化(Encryption at Rest)と転送時暗号化(Encryption in Transit)の違い、S3/EBS/RDS/DynamoDBの暗号化設定、TLS強制方法、KMSとの統合、エンドツーエンド暗号化設計を解説。

一言結論

保存時と転送時の両方の暗号化が必要であり、RDSとEBSは作成後に暗号化を有効化できないため設計段階で有効化することが鉄則で、S3バケットポリシーでaws:SecureTransport=falseをDenyしてHTTPSを強制することも必須の設定だ。

保存時暗号化 vs 転送時暗号化

保存時暗号化(Encryption at Rest):
  → ディスク/ストレージに保存されたデータの暗号化
  → 物理媒体の盗難・不正アクセスからデータを保護
  → KMSとの統合で鍵管理を一元化

転送時暗号化(Encryption in Transit):
  → ネットワーク通信中のデータの暗号化
  → 通信の傍受・中間者攻撃からデータを保護
  → TLS/SSL(HTTPS、FTPS等)で実現
  
両方必要な理由:
  保存時のみ: 通信を傍受される
  転送時のみ: ストレージを物理的に取り出されると読める
  → 両方の脅威に対応するため、両方の暗号化が必要

S3 の暗号化

保存時暗号化:
  SSE-S3(デフォルト): AWSが鍵を完全管理
  SSE-KMS: KMSで鍵を管理(CMK使用時は監査が可能)
  SSE-C: クライアントが鍵を管理(AWSは鍵を保存しない)
  クライアントサイド暗号化: アップロード前に暗号化

転送時暗号化(HTTPS強制):
{
  "Statement": [{
    "Effect": "Deny",
    "Principal": "*",
    "Action": "s3:*",
    "Resource": [
      "arn:aws:s3:::my-bucket",
      "arn:aws:s3:::my-bucket/*"
    ],
    "Condition": {
      "Bool": {
        "aws:SecureTransport": "false"
      }
    }
  }]
}

EBS の暗号化

# EBSのデフォルト暗号化を有効化(アカウントレベル)
aws ec2 enable-ebs-encryption-by-default
aws ec2 modify-ebs-default-kms-key-id \
  --kms-key-id arn:aws:kms:ap-northeast-1:123456789012:key/xxx

# 暗号化されたボリュームの作成
aws ec2 create-volume \
  --availability-zone ap-northeast-1a \
  --volume-type gp3 \
  --size 100 \
  --encrypted \
  --kms-key-id arn:aws:kms:ap-northeast-1:123456789012:key/xxx
EBS暗号化の特徴:
  → EC2とEBS間の通信も暗号化される
  → スナップショットも自動的に暗号化される
  → 暗号化されたスナップショットは暗号化されたボリュームにのみ復元可
  → 未暗号化ボリュームを暗号化に変更する手順:
    1. スナップショット作成
    2. スナップショットをコピー(暗号化オプション有効)
    3. 暗号化されたスナップショットから新ボリュームを作成

RDS/Aurora の暗号化

# 暗号化を有効にしてRDSを作成
aws rds create-db-instance \
  --db-instance-identifier my-db \
  --db-instance-class db.t3.medium \
  --engine mysql \
  --master-username admin \
  --master-user-password password123 \
  --storage-encrypted \
  --kms-key-id arn:aws:kms:ap-northeast-1:123456789012:key/xxx
RDS暗号化の特徴:
  → 作成時のみ指定可能(後から有効化できない)
  → 既存DBを暗号化: スナップショット → 暗号化コピー → 復元
  → 転送時暗号化: 証明書バンドルをDLし接続で--ssl-caを指定
  → Performance Insights、拡張監視もKMSで暗号化可能

DynamoDB の暗号化

# DynamoDB テーブルの暗号化(デフォルトはAWS管理キー)
aws dynamodb create-table \
  --table-name Orders \
  --attribute-definitions AttributeName=orderId,AttributeType=S \
  --key-schema AttributeName=orderId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST \
  --sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=arn:aws:kms:...
DynamoDB暗号化の特徴:
  → デフォルトで保存時暗号化が有効(AWS管理キー)
  → CMKに変更: SSEType=KMS + KMSMasterKeyId
  → DynamoDB Streams: 別途KMS設定が必要
  → DAX: インメモリデータは暗号化されない(転送中はTLS)

サービス別暗号化サマリー

デフォルトで暗号化されているもの(設定不要):
  DynamoDB: ✅(AWS管理キー)
  Lambda: ✅(環境変数はKMS必要)
  CloudWatch Logs: ✅(AWSキー)
  SQS: ✅(サーバーサイド暗号化オプションあり)
  
設定が必要なもの:
  S3: デフォルト暗号化を有効化(SSE-S3は無料)
  EBS: デフォルト暗号化を有効化(アカウントレベル)
  RDS: 作成時に--storage-encryptedを指定
  ElastiCache: 保存時/転送時ともに明示的に有効化

KMS を使ったエンベロープ暗号化フロー

アプリケーション → KMS GenerateDataKey

              プレーンテキストデータキー(一時使用)
              暗号化データキー(保存用)

アプリケーション → プレーンテキストキーでデータ暗号化
→ 暗号化データ + 暗号化データキーをS3に保存
→ プレーンテキストキーはメモリから廃棄

復号時:
アプリケーション → 暗号化データキーをKMS Decryptに送信

                プレーンテキストキーを取得

アプリケーション → プレーンテキストキーでデータ復号

試験頻出ポイント

シナリオ回答
S3へのHTTP接続を禁止バケットポリシーにaws:SecureTransport: false でDeny
RDSを暗号化に変更したい(既存)スナップショット→暗号化コピー→復元
アプリが鍵を管理してS3に暗号化SSE-C(クライアント管理キー)
KMSキーの使用状況を監査したいCloudTrail(KMS API呼び出しを記録)
全EBSボリュームを自動で暗号化アカウントデフォルト暗号化を有効化

まとめ

保存時暗号化(KMS統合)と転送時暗号化(TLS/HTTPS強制)の両方を適用することが重要だ。RDS/EBSは作成時の指定が必要で後から変更できない制約に注意する。S3バケットポリシーでHTTPSを強制することが推奨設定だ。