次の方法で共有


ASP.NET Core でのサブキーの派生と認証された暗号化

キー リング内のほとんどのキーには、何らかの形式のエントロピが含まれており、"CBC モード暗号化 + HMAC 検証" または "GCM 暗号化 + 検証" を示すアルゴリズム情報が含まれます。 このような場合、埋め込みエントロピをこのキーのマスター キーマテリアル (または KM) と呼び、実際の暗号化操作に使用されるキーを派生させるキー派生関数を実行します。

キーは抽象であり、カスタム実装は次のように動作しない可能性があります。 組み込みのファクトリの 1 つを使用するのではなく、キーが独自の IAuthenticatedEncryptor の実装を提供する場合、このセクションで説明するメカニズムは適用されなくなります。

追加の認証済みデータとサブキーの派生

IAuthenticatedEncryptor インターフェイスは、認証されたすべての暗号化操作のコア インターフェイスとして機能します。 その Encrypt メソッドは、プレーンテキストと additionalAuthenticatedData (AAD) の 2 つのバッファーを受け取ります。 プレーンテキストコンテンツフローは IDataProtector.Protectの呼び出しを変更しませんが、AAD はシステムによって生成され、次の 3 つのコンポーネントで構成されます。

  1. このバージョンのデータ保護システムを識別する 32 ビットマジック ヘッダー 09 F0 C9 F0。

  2. 128 ビットキー ID。

  3. この操作を実行する IDataProtector を作成した目的チェーンから形成された可変長文字列。

AAD は 3 つのコンポーネントすべてのタプルに対して一意であるため、すべての暗号化操作で KM 自体を使用する代わりに、それを使用して KM から新しいキーを派生させることができます。 IAuthenticatedEncryptor.Encryptの呼び出しごとに、次の主要な派生プロセスが実行されます。

( K_E, K_H ) = SP800_108_CTR_HMACSHA512(K_M, AAD, contextHeader || keyModifier)

ここでは、次のパラメーターを使用して、NIST SP800-108 KDF をカウンター モードで呼び出します ( NIST SP800-108、Sec. 5.1 を参照)。

  • キー派生キー (KDK) = K_M

  • PRF = HMACSHA512

  • label = 追加認証データ

  • context = contextHeader ||keyModifier

コンテキスト ヘッダーは可変長であり、基本的には、 K_EK_Hを派生させるアルゴリズムの拇印として機能します。 キー修飾子は、 Encrypt の呼び出しごとにランダムに生成される 128 ビット文字列であり、KDF への他のすべての入力が一定であっても、KE と KH がこの特定の認証暗号化操作で一意である可能性が圧倒的に高くなることを保証します。

CBC モード暗号化 + HMAC 検証操作の場合、 | K_E | は対称ブロック暗号キーの長さであり、 | K_H | は HMAC ルーチンのダイジェスト サイズです。 GCM 暗号化と検証操作の場合は、 | K_H | = 0

CBC モード暗号化 + HMAC 検証

上記のメカニズムを使用して K_E が生成されると、ランダムな初期化ベクトルを生成し、対称ブロック暗号アルゴリズムを実行してプレーンテキストを暗号化します。 その後、初期化ベクトルと暗号テキストは、MAC を生成するキー K_H で初期化された HMAC ルーチンを介して実行されます。 このプロセスと戻り値は、下にグラフィカルに表されます。

CBC モードのプロセスと戻り値

output:= keyModifier || iv || E_cbc (K_E,iv,data) || HMAC(K_H, iv || E_cbc (K_E,iv,data))

IDataProtector.Protect実装では、出力の先頭にマジック ヘッダーとキー IDを追加してから、呼び出し元に返されます。 マジック ヘッダーとキー ID は暗黙的に AAD の一部であり、キー修飾子は KDF への入力として供給されるため、これは、最終的に返されたペイロードのすべての 1 バイトが MAC によって認証されることを意味します。

Galois/Counter Mode の暗号化と検証

上記のメカニズムを介して K_E 生成されると、ランダムな 96 ビット nonce を生成し、対称ブロック暗号アルゴリズムを実行してプレーンテキストを暗号化し、128 ビット認証タグを生成します。

GCM モードのプロセスと戻り値

output := keyModifier || nonce || E_gcm (K_E,nonce,data) || authTag

GCM は AAD の概念をネイティブにサポートしていますが、AAD は元の KDF にのみ供給され、空の文字列を AAD パラメーターの GCM に渡す方法を選択しています。 その理由は 2 つあります。 まず、 機敏性をサポートするためにK_M を暗号化キーとして直接使用することは決して望んではいありません。 さらに、GCM では、入力に非常に厳密な一意性の要件が課されます。 同じ (キー、nonce) ペアを持つ 2 つ以上の個別の入力データ セットで GCM 暗号化ルーチンが呼び出される確率は、2^-32 を超えてはなりません。 K_E修正した場合、2^-32 制限の違反を実行する前に、2^32 を超える暗号化操作を実行することはできません。 これは非常に多くの操作のように見えるかもしれませんが、トラフィックの多い Web サーバーは、これらのキーの通常の有効期間内で、わずか数日で 40 億件の要求を処理できます。 2^-32 の確率制限に準拠し続けるために、引き続き 128 ビットキー修飾子と 96 ビット nonce を使用します。これにより、特定の K_Mの使用可能な操作数が大幅に拡張されます。 設計をわかりやすくするために、CBC と GCM 操作の間で KDF コード パスを共有します。AAD は KDF で既に考慮されているため、GCM ルーチンに転送する必要はありません。