TL

エンベロープ暗号化と KMS の原理

テラバイトのデータを KMS に通さず高速に暗号化できる仕組みが分かる。データ鍵をマスター鍵で包む二層構造、データ鍵キャッシュ、GenerateDataKey/Decrypt API を原理から押さえられる。

応用KMSエンベロープ暗号化鍵管理暗号化クラウドセキュリティ最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.エンベロープ暗号化はデータ鍵(DEK)で実データを暗号化し、その DEK をマスター鍵(KEK)で暗号化(ラップ)して並べて保管する二層構造。マスター鍵は KMS の HSM 境界から外へ出ない。
  • 2.全データを KMS に流さない理由は性能・コスト・転送量。大きな平文はローカルの DEK で暗号化し、KMS には数十バイトの DEK のラップ/アンラップだけを依頼するため、KMS は処理量とは無関係に一定負荷で済む。
  • 3.GenerateDataKey は平文 DEK と暗号化済み DEK を1回で返す API。平文 DEK は暗号化に使い終えたら即座にメモリから消し、暗号化済み DEK だけを暗号文に添えて保存。復号時は Decrypt で DEK を取り戻す。

エンベロープ暗号化が解く問題:鍵保管と性能の両立

データを暗号化すれば、暗号文を守る責任は鍵を守る責任に置き換わります。鍵が漏れれば暗号文は無意味になり、鍵を失えばデータは永久に読めなくなる。ここで素朴な疑問が生じます。「鍵を安全な金庫(HSM や KMS)に預けるなら、いっそデータも全部その金庫に通して暗号化すればいいのでは?」と。

これが破綻するのは性能とコストです。クラウド KMS のマスター鍵は耐タンパなハードウェア境界の内側にあり、平文を境界外へ出しません。つまり KMS に直接暗号化を依頼するには、対象の平文を毎回ネットワーク越しに KMS へ送る必要があります。数百 GB のオブジェクトや毎秒数万件のレコードをすべて KMS に通せば、転送量・レイテンシ・API 課金が爆発します。多くのクラウド KMS は1回の暗号化リクエストで扱える平文を数 KB 程度に制限しており、そもそも大きなデータを直接渡せません。

**エンベロープ暗号化(envelope encryption)はこの矛盾を二層の鍵で解きます。実データは手元で生成したデータ暗号化鍵(DEK: Data Encryption Key)でローカルに暗号化し、その DEK だけを KMS のマスター鍵(KEK: Key Encryption Key)**で暗号化して暗号文に添える。重い処理(実データの暗号化)はローカルの CPU が担い、KMS は軽い処理(数十バイトの DEK の暗号化)だけを担う。封筒(envelope)に手紙(データ)を入れ、封筒の鍵だけを金庫に預ける比喩から名付けられています。

なぜ全データを KMS に通さないのか

理由は突き詰めると三つです。(1) 性能:大きな平文を毎回 KMS へ往復させればネットワークレイテンシが処理時間を支配する。(2) コスト:KMS は API 呼び出し回数で課金されるため、レコード単位で呼べば天文学的になる。(3) 制限:マスター鍵で直接暗号化できる平文サイズは数 KB に制限される。エンベロープ暗号化なら、データ量がいくら増えても KMS への負荷は「DEK のラップ/アンラップ」という一定量に固定され、性能とコストがデータ量から切り離されます。

二層構造:DEK で包み、KEK で DEK を包む

鍵の階層は二段です。下層の DEK が実データを暗号化し、上層の KEK(マスター鍵)が DEK を暗号化します。保存されるのは「暗号化された実データ」と「暗号化された DEK」の組です。

暗号化(書き込み時):

  平文データ ──[ DEK で暗号化 ]──▶ 暗号文データ
                                        │
  DEK ──[ KEK で暗号化 (ラップ) ]──▶ 暗号化済み DEK
                                        │
                                        ▼
  保存される組: { 暗号文データ, 暗号化済み DEK }
                 (平文 DEK はメモリから消去して残さない)

決定的なのは、平文の DEK をどこにも永続化しない点です。DEK は実データを暗号化する一瞬だけメモリ上に存在し、暗号化が終われば破棄します。残すのは KEK でラップされた暗号化済み DEK だけ。これを暗号文のすぐ隣(オブジェクトのメタデータや DB の同一行)に置きます。暗号化済み DEK は、KEK なしには絶対に平文へ戻せないため、暗号文と一緒に流出しても安全です。

この構造は鍵階層と鍵ラッピングの一般原理そのもので、HSM と鍵保護で扱うマスター鍵による入れ子保護をクラウド API として提供したものと整理できます。実データを実際に暗号化するのは下層の DEK なので、その暗号化方式には完全性も同時に守るAEAD(認証付き暗号)を使うのが定石です。

ラップ/アンラップという用語

KEK で DEK を暗号化することをラップ(wrap)、KEK で暗号化済み DEK を復号することを**アンラップ(unwrap)**と呼びます。鍵を別の鍵で「包む/開く」というニュアンスで、データの暗号化/復号とは区別して使われます。エンベロープ暗号化は要するに「DEK のラップ階層」です。

API の原理:GenerateDataKey・Encrypt・Decrypt

クラウド KMS(AWS KMS・Google Cloud KMS・Azure Key Vault など)は、この二層構造を3つの基本 API で支えます。中核は GenerateDataKey です。

GenerateDataKey が平文 DEK と暗号化済み DEK を一度に返すのがエンベロープ暗号化の起点。
API入力出力役割
GenerateDataKeyKEK の ID平文 DEK + 暗号化済み DEKDEK を生成し、平文と KEK ラップ版を同時に返す
EncryptKEK の ID + 小さな平文(数 KB 以下)暗号文小さなデータを KEK で直接暗号化(DEK 不要)
Decrypt暗号化済み DEK(または暗号文)平文 DEK(または平文)KEK でアンラップして元に戻す

GenerateDataKey の妙は、平文 DEK と暗号化済み DEK を1回の呼び出しで両方返すことにあります。KMS は内部のCSPRNGでランダムな DEK を生成し、その平文 DEK をレスポンスで返すと同時に、同じ DEK を KEK でラップした暗号化済み DEK も返します。アプリの手順はこうです。

書き込み(暗号化)の流れ:

  1. KMS.GenerateDataKey(KEK_id)
        → { plaintext_dek, encrypted_dek } を受け取る
  2. plaintext_dek で実データをローカル暗号化 (AES-GCM 等)
        → ciphertext
  3. plaintext_dek をメモリから即座にゼロクリア(破棄)
  4. 保存: { ciphertext, encrypted_dek }
読み込み(復号)の流れ:

  1. 保存済みの encrypted_dek を取り出す
  2. KMS.Decrypt(encrypted_dek) → plaintext_dek を受け取る
  3. plaintext_dek で ciphertext を復号 → 平文データ
  4. plaintext_dek をメモリから破棄

復号時は Decrypt に暗号化済み DEK を渡せば、KMS が KEK でアンラップして平文 DEK を返します。アプリはそれで実データを復号する。マスター鍵 KEK は一度もアプリ側へ出てこない点に注目してください。アプリが扱うのは常に DEK までで、KEK は KMS の HSM 境界に固定されたままです。だから KMS の認可(IAM 権限)を失えば、暗号化済み DEK を持っていても誰も復号できません。これがアクセス制御の取り消しを「鍵の物理破棄なしに」実現する核心です。

なお Encrypt は DEK を介さず KEK で小さな平文を直接暗号化する API で、設定値や別の鍵そのものを守る用途に向きます。大きなデータには使えない(サイズ制限)ため、本命は GenerateDataKey です。

データ鍵キャッシュ:KMS 呼び出しを減らす

エンベロープ暗号化でも、レコードごとに毎回 GenerateDataKey / Decrypt を呼べば KMS への往復が処理性能の足かせになります。そこで**データ鍵キャッシュ(data key caching)**を使い、取得した DEK を一定期間メモリに保持して複数の暗号化/復号で再利用します。

考え方は、1本の DEK を「使い捨て」ではなく「期限付きで使い回す」ことです。GenerateDataKey で得た平文 DEK(とその暗号化済み版)をローカルにキャッシュし、有効期間内に届いた複数のメッセージを同じ DEK で暗号化する。KMS 呼び出し回数が激減し、レイテンシとコストが大きく下がります。ただし鍵の再利用は安全性とのトレードオフであり、上限を厳格に設けるのが原則です。

再利用を許す代わりに、時間・件数・量の3軸で上限を課して暴露を抑える。
キャッシュ上限意味なぜ要るか
有効期間 (TTL)DEK をキャッシュに置ける最大時間古い鍵の滞留を防ぎ、ローテーションを促す
メッセージ数上限1本の DEK で暗号化できる最大件数鍵あたりの暗号化量を抑え、暴露面を限定
バイト数上限1本の DEK で暗号化できる最大バイトAES-GCM 等の nonce 空間の枯渇を回避
鍵の使い回しには上限が必須

データ鍵キャッシュは性能のために DEK を再利用しますが、同じ鍵で暗号化するデータが増えるほど、その鍵が漏れたときの被害範囲(暴露面)が広がります。さらに AEAD の GCM 等は、同じ鍵で nonce を使い回すと壊滅的に破れるため、1本の DEK で扱う件数・バイト数には上限が要ります。キャッシュは「TTL・件数・バイト数」の上限に達したら必ず DEK を破棄して新しい鍵を取り直す設計にします。上限なしの無期限キャッシュは、エンベロープ暗号化の安全性を自ら崩す誤りです。

暗号化コンテキストと鍵ローテーション

実務の KMS には、二層構造を補強する仕組みがあります。一つは**暗号化コンテキスト(encryption context)**です。GenerateDataKey や Decrypt の際に「このテナント ID・このテーブル」といった追加データを指定すると、それが AEAD の関連データ(AAD)として DEK のラップに織り込まれます。復号時に同じコンテキストを渡さなければアンラップが失敗するため、暗号化済み DEK を別の文脈へ流用する攻撃を防げます。これは認証の効く文脈束縛で、AEAD の関連データの応用です。

もう一つは鍵ローテーションです。エンベロープ構造ではマスター鍵 KEK を新しい版に差し替えても、実データを暗号化している DEK には一切触れる必要がありません。KEK 更新後は、暗号化済み DEK を「旧 KEK でアンラップ→新 KEK で再ラップ」するだけで、巨大な実データを再暗号化せずに最上位の鍵を入れ替えられます。多くの KMS は KEK の版管理を内部で行い、暗号化済み DEK に鍵版 ID を埋め込むことで、復号時に正しい版の KEK を自動選択します。

鍵の保管・配布・ローテーションをサービスとして体系化したのが KMS であり、その運用思想はアプリ全体の認証情報を扱うシークレット管理と地続きです。

まとめ

エンベロープ暗号化の本質は、重い暗号化はローカルの DEK に、鍵の保護は KMS のマスター鍵にと役割を二層に分けることです。実データは手元の DEK で高速に暗号化し、その DEK だけを KEK でラップして暗号文に添える。マスター鍵 KEK は HSM 境界から出ないため、暗号化済み DEK が暗号文ごと流出しても KMS の認可なしには復号できません。

全データを KMS に通さない理由は、性能・コスト・サイズ制限の三つに集約されます。GenerateDataKey が平文 DEK と暗号化済み DEK を一度に返すことが起点で、平文 DEK は使い終え次第破棄し、Decrypt で必要時に取り戻す。データ鍵キャッシュは KMS 呼び出しを減らしますが、TTL・件数・バイト数の上限で暴露面を抑えることが安全運用の条件です。鍵を物理で守る土台はHSM と鍵保護、DEK で実データを守る暗号方式はAEADを合わせて参照してください。

セキュリティ Article

エンベロープ暗号化と KMS の原理を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

KMS

比較で見る軸

難易度: advanced / カテゴリ: セキュリティ / タグ数: 5

導入後に効く点

全データを KMS に流さない理由は性能・コスト・転送量。大きな平文はローカルの DEK で暗号化し、KMS には数十バイトの DEK のラップ/アンラップだけを依頼するため、KMS は処理量とは無関係に一定負荷で済む。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
セキュリティ
タグ数
5

判断チェックリスト

  • 自社の用途が「KMS / エンベロープ暗号化」に近いか確認する。
  • 強みである「エンベロープ暗号化はデータ鍵(DEK)で実データを暗号化し、その DEK をマスター鍵(KEK)で暗号化(ラップ)して並べて保管する二層構造。マスター鍵は KMS の HSM 境界から外へ出ない。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

KMSエンベロープ暗号化鍵管理暗号化クラウドセキュリティKMSエンベロープ暗号化鍵管理
参考: 公式情報