← AWSサービスの内部原理 コース
62. KMSキーは外に出ない — 鍵を渡さず『操作を頼む』APIの設計
「鍵をください」ではなく「この暗号化をやってください」——KMSのAPIがなぜこの形になるのか、鍵が一度も外に出ない内部構造を上から下へ図で追っていきます。
① 前提: 秘密は移動させるほど漏れる
素朴な発想鍵をダウンロードして手元で暗号化
鍵がネットワークを流れ、ディスクやメモリダンプに残るAPIで渡すのは「やってほしいこと」だけ
KMSの発想鍵は置いたまま「操作」だけを頼む
平文の鍵はKMSの境界を一度も越えないEncryptこの4KBを暗号化して
Decryptこの暗号文を復号して
GenerateDataKey外で使う鍵を1本発行して
- 公式の言い回し — KMSキーは「FIPS 140-3 Security Level 3 validated hardware security modules (HSM)」で保護され、「They never leave AWS KMS unencrypted」。
これはSigV4レッスンと全く同じ発想だ。あのときシークレットキーそのものを送らず、HMACという「証明」だけを送った。KMSはそれを暗号鍵に適用する——鍵を渡さず、鍵を使った「結果」だけを返す。
② HSMという信頼の根(root of trust)
HSMFIPS 140-3 Security Level 3 認証の専用ハードウェア
物理的な信頼の根TLSで送る
リクエストあなた(またはAWSサービス)から
結果だけがTLSで返る
HSM内で演算平文の鍵がこの物理境界を越える経路は設計上存在しない
結果を受領KMSは暗号文も復号結果も保存しない
- 公式: "The returned ciphertext, or the decrypted payload, is never stored within AWS KMS" — 演算結果はTLS接続で呼び出し元に返るだけで、KMS側には残らない。
- AWSサービスが代理で呼ぶ場合も同じ("This also applies to calls made by AWS services on your behalf.")。
ハードウェアを信頼の根にする発想は、Lambda編のFirecrackerで見た「ハードウェア支援による分離」と同じ系譜だ。ソフトの約束ではなく物理で保証する、という一段強い保証の作り方である。
③ 鍵は4段の階層になっている
ドメインキー256-bit AES-GCM / HSMのメモリ内にのみ存在
日次ローテーション*暗号化するたびに導出
HBK256-bit対称鍵 または RSA/楕円曲線の秘密鍵
これが集まって1つの「KMSキー(keyId)」になる / 年次ローテーション(任意)これだけが平文で外に出られる
導出暗号化キー256-bit AES-GCM / HSMのメモリ内のみ
使い捨て(encryptで1回、decryptで再生成)CDKカスタマーデータキー。HBKで暗号化され、TLSで認可ユーザーに返る
- * ドメインキーは日次ローテーションだが、ドメイン管理・構成作業の都合で「最大でも週次」まで緩められることがある(公式注記)。
- HBKのローテーションは新旧を並存させる(⑤参照)。
上3段(ドメインキー・HBK・導出鍵)はHSMのメモリから決して平文で出ない。外の世界に出られるのは最下段のCDKだけ——しかも平文と暗号文の両方の形で。この非対称性が次のAPI分担を生む。
④ だからAPIは「操作を頼む」形になる
データのサイズは?暗号化したいデータで分岐
左: 暗号文だけ返る / 右: 戻り値は2つ
Encrypt / DecryptデータをKMSに送り、HSM内で暗号/復号
GenerateDataKey外で使うデータキーを1本発行
平文コピーで手元の大きいデータを暗号化
平文コピーすぐ使って捨てる
暗号文コピーデータに添えて保存
エンベロープ暗号化封筒(エンベロープ)暗号化の完成形
- Encryptの平文上限はSYMMETRIC_DEFAULTで4,096バイト(公式: "Encrypts plaintext of up to 4,096 bytes")。
- GenerateDataKeyは "a plaintext data key and an encrypted copy of that data key" を返す。
Encryptで大きなファイルを扱わないのは制限ではなく設計だ。KMSを毎バイト通せば遅く高価になる。だからGenerateDataKeyで鍵を1本もらい、重い暗号化は手元で高速に行い、鍵の暗号文だけをデータに添える——これがエンベロープ暗号化の骨子である。
⑤ ローテーションは「差し替え」ではなく「追加」
KMSキー(keyId)実体はHBKの束
ローテーション実行 = 新しいHBKを「追加」(差し替えではない)
HBK v1唯一のactiveな鍵材料
HBK v1過去の暗号文の復号に使う
HBK v2 (active)新規の暗号化はactiveなHBKだけが担当
- 公式: "The older HBKs are preserved and can be used to decrypt and verify previously protected data. But only the active cryptographic key can be used to protect new information."
- 暗号文にはどのHBKで作られたかの情報が埋まっているため、復号時に正しい版が選ばれる。
古いデータを再暗号化しなくていいのは、鍵が「版(バージョン)」として積み重なるからだ。DynamoDB編で見た追記ログと同じ発想——上書きせず追加する構造が、過去への影響を断ち切って安全な変更を可能にしている。