大規模アプリケーションで暗号化を設計する際、対称鍵暗号アルゴリズムの暗号化限界(データ境界)は見過ごされがちな重要な考慮事項です。特に AES-GCM のような認証付き暗号化方式では、同一の鍵で暗号化できるデータ量に明確な上限があります。本記事では、AWS Key Management Service(AWS KMS)と AWS Encryption SDK がどのようにこの境界問題を解決しているのか、その仕組みを解説します。
AES-GCM の暗号化限界とデータ境界の課題
AES-GCM(Galois Counter Mode)は、高いパフォーマンスと認証機能を兼ね備えた暗号化モードとして広く採用されています。しかし、この方式には「暗号化限界」と呼ばれる重要な制約が存在します。
第一に、同一の鍵 K と初期化ベクトル(IV)の組み合わせが重複すると、セキュリティ特性が損なわれます。NIST SP 800-38D では、鍵と IV の再使用確率を 2^-32(約43億分の1)未満に抑えることが求められています。ランダムな IV を使用する場合、2^32 回の暗号化ごとに鍵を更新する必要があります。
第二に、単一の暗号化操作で処理できるデータ量にも上限があります。AES-GCM のブロックカウンターは32ビットであり、(K, IV) ペアあたり最大 2^32-2 ブロック(約68.72 GB)までという制約です。
第三に、単一の鍵 K で暗号化できる総データ量にも上限があります。NIST は 2^68 バイトを推奨していますが、AWS はより保守的なセキュリティマージンを採用し、識別不可能性確率を 2^-32 未満に維持しています。

これらの制約を手動で管理しようとすると、暗号化ごとのカウント管理や鍵のローテーション判断が必要となり、実装の複雑さとエラーのリスクが増大します。
派生鍵方式による一意鍵生成のしくみ
AWS KMS と AWS Encryption SDK は、この境界問題を解決するために「派生鍵方式」を採用しています。この方式では、メインの鍵 K から各暗号化操作ごとに一意の派生鍵 Kd を生成し、実際の暗号化には派生鍵を使用します。
仕組みはシンプルです。暗号化のたびにランダムなノンス(ナンス)N を生成し、これを鍵導出関数(KDF)に入力して派生鍵を得ます。
Kd = KDF(K, N, context)ノンス N は暗号化ごとにランダムに生成されるため、同じメイン鍵 K から何度でも異なる派生鍵 Kd を導出できます。これにより、メイン鍵の使用回数制限を大幅に緩和できるのです。
直感的に言えば、128ビットのランダムノンスを使用することで、メイン鍵に対する暗号化回数の制限を 2^32 回からはるかに大きな値へと拡大できます。AWS KMS では、最大4 KB のペイロードサイズ制限と組み合わせることで、NIST やより保守的な制限を十分に下回るデータ量しか暗号化鍵の下で保護されないことを保証しています。
鍵導出関数(KDF)とノンスの活用
鍵導出関数(KDF)は、暗号学的に安全な方法で鍵材料から新しい鍵を導出する関数です。KDF は以下の入力を受け取ります。
- K:メインの鍵(鍵導出のソース)
- label:アプリケーションや呼び出し固有の値
- context:呼び出し固有のコンテキスト情報
- N:呼び出しごとのランダムノンス
- LKm:出力長(バイト単位)
出力として鍵材料 Kmat が生成されます。
Kmat = KDF(K, label, context, N, LKm)AWS KMS では、NIST SP 800-108r1 カウンターモード KDF を採用し、HMAC-SHA256 を疑似乱数関数として使用して256ビットの鍵材料を生成します。具体的には、次のように派生鍵を計算します。
Kd = HMAC-SHA256(K, ctx)ここで ctx は、カウンター値、定数、およびノンス N を連結したものです。
一方、AWS Encryption SDK のデフォルト設定では、HKDF(HMAC-based Extract-and-Expand Key Derivation Function)を SHA512 と共に使用します。ノンスは256ビットであり、次のように派生鍵を生成します。
Kd = HKDF(K, salt=label, info=context, 32)
この KDF ベースのアプローチにより、各暗号化呼び出しで一意の鍵が使用されることが保証され、AES-GCM の暗号化限界を気にする必要がなくなります。
AWS KMS での実装詳細
AWS KMS は、対称暗号化のために AES-GCM with 256-bit keys を使用します。Encrypt API を呼び出すと、以下の処理が行われます。
まず、指定されたカスタマーマネージドキー(CMK)から派生鍵を導出します。AWS KMS は128ビットのランダムノンス N を生成し、これと CMK を使用して KDF により256ビットの対称暗号化鍵を生成します。
次に、96ビットのランダム IV を生成し、派生鍵を使用して平文を AES-GCM で暗号化します。
(C, T) = AES-GCM(Kd, IV, AAD, P)AWS KMS の Encrypt API には4 KB のペイロードサイズ制限があります。この制限により、単一の暗号化鍵の下で暗号化されるデータ量は、NIST の推奨制限や AWS の保守的な制限をはるかに下回ることが保証されています。
重要なのは、この処理が完全に自動化されている点です。利用者は暗号化限界を意識する必要がなく、Key ID を指定するだけで安全に暗号化できます。
AWS Encryption SDK のアプローチ
AWS Encryption SDK は、クライアントサイド暗号化のためのライブラリです。デフォルト設定では、データを4 KB のフレームに分割して暗号化します。
各メッセージの暗号化では、次の処理が行われます。
まず、ランダムな256ビット値とメイン鍵 K、および呼び出し固有のコンテキストを使用して、HKDF により派生鍵 Kd を導出します。
次に、各フレーム P_f を派生鍵 Kd と決定論的 IV で AES-GCM 暗号化します。
(C, T) = AES-GCM(Kd, IV, AAD, Pf)4 KB フレームサイズにより、単一の暗号化鍵の下で暗号化できるデータ量は最大 2^44 バイト(2^32 フレーム × 4 KB)に制限されます。これは NIST の推奨制限(2^68 バイト)や AWS の保守的な要件(識別不可能性確率 2^-32 未満)を十分に満たしています。
データキーキャッシングを使用する場合でも、AWS Encryption SDK はアルゴリズムスイートに KDF を含むデータキーのみをキャッシュします。このため、暗号化限界に達することなく、安全にデータキーを再利用できます。
まとめ 手動管理が不要になる実践的メリット
AWS KMS と AWS Encryption SDK が採用する派生鍵方式は、AES-GCM の暗号化限界という複雑な問題をサービス側で自動的に解決してくれます。これにより、開発者とアーキテクトは以下のメリットを享受できます。
実装の簡素化:暗号化回数のカウントや鍵のローテーション判断を手動で行う必要がありません。サービスが自動的に適切なタイミングで派生鍵を生成します。
セキュリティの向上:暗号化限界の計算ミスや見落としによる脆弱性を防げます。AWS は NIST の推奨以上の保守的なセキュリティマージンを適用しています。
スケーラビリティの確保:大規模アプリケーションでも、暗号化限界を気にせずにスループットを確保できます。データキーキャッシングを活用すれば、API 呼び出しのオーバーヘッドも削減可能です。
実装時のベストプラクティスとして、以下の点に注意してください。
- AWS KMS では、Encrypt API の4 KB 制限を理解した上で、大きなデータは AWS Encryption SDK で処理する
- AWS Encryption SDK のデフォルト設定をそのまま使用することで、暗号化限界を自動的に回避できる
- データキーキャッシングが必要な場合は、maximum age、maximum messages encrypted、maximum bytes encrypted のしきい値を適切に設定する
- 常に最新バージョンの SDK を使用し、セキュリティ修正を適用する
AWS KMS と AWS Encryption SDK を活用することで、対称暗号化の境界問題を意識することなく、安全かつ効率的な暗号化システムを構築できます。複雑な鍵管理を AWS に任せ、アプリケーション開発の本質的な課題に集中できる環境を整えましょう。

















