次の方法で共有


ASP.NET Core のコンテキスト ヘッダー

背景と理論

データ保護システムでは、"キー" とは、認証された暗号化サービスを提供できるオブジェクトを意味します。 各キーは一意の ID (GUID) で識別され、アルゴリズム情報とエントロピックマテリアルが含まれます。 各キーが一意のエントロピを実行することを目的としていますが、システムはそれを強制することはできません。また、キー リング内の既存のキーのアルゴリズム情報を変更することで、キー リングを手動で変更する可能性がある開発者を考慮する必要があります。 このような場合に、セキュリティ要件を達成するために、データ保護システムには 暗号化機敏性の概念があり、複数の暗号化アルゴリズム間で単一のエントロピック値を安全に使用できます。

暗号化の機敏性をサポートするほとんどのシステムでは、ペイロード内にアルゴリズムに関する識別情報を含めることで行われます。 アルゴリズムの OID は、通常、この候補として適しています。 ただし、問題の 1 つは、同じアルゴリズムを指定する複数の方法があることです。"AES" (CNG) と、マネージド Aes、AesManaged、AesCryptoServiceProvider、AesCng、および RijndaelManaged (特定のパラメーターを指定) クラスはすべて実際に同じものであり、これらのすべてのマッピングを正しい OID に維持する必要があります。 開発者がカスタム アルゴリズム (または AES の別の実装) を提供する必要がある場合は、その OID を伝える必要があります。 この追加の登録手順により、システム構成が特に痛みを伴います。

一歩下がると、間違った方向から問題に近づいていると判断しました。 OID はアルゴリズムの内容を示しますが、実際にはこれは気にしません。 2 つの異なるアルゴリズムで単一のエントロピック値を安全に使用する必要がある場合、アルゴリズムが実際に何であるかを知る必要はありません。 私たちが実際に気にしているのは、それらがどのように動作するかです。 適切な対称ブロック暗号アルゴリズムは、強力な擬似ランダム順列 (PRP) でもあります。入力 (キー、チェーン モード、IV、プレーンテキスト) を修正すると、暗号テキストの出力は、同じ入力を指定した他の対称ブロック暗号アルゴリズムとは異なる圧倒的な確率で出力されます。 同様に、適切なキー付きハッシュ関数も強力な擬似乱数関数 (PRF) であり、固定入力セットを指定すると、その出力は他のキー付きハッシュ関数とは圧倒的に異なります。

この強力な PRP と PRF の概念を使用して、コンテキスト ヘッダーを構築します。 このコンテキスト ヘッダーは、基本的に、特定の操作で使用されているアルゴリズムに対して安定した拇印として機能し、データ保護システムに必要な暗号化の機敏性を提供します。 このヘッダーは再現可能であり、後で サブキー派生プロセスの一部として使用されます。 基になるアルゴリズムの操作モードに応じて、コンテキスト ヘッダーを構築する方法は 2 つあります。

CBC モード暗号化 + HMAC 認証

コンテキスト ヘッダーは、次のコンポーネントで構成されます。

  • [16 ビット]値 00 00 は、"CBC 暗号化 + HMAC 認証" を意味するマーカーです。

  • [32 ビット]対称ブロック暗号アルゴリズムのキー長 (バイト単位、ビッグ エンディアン)。

  • [32 ビット]対称ブロック暗号アルゴリズムのブロック サイズ (バイト単位、ビッグ エンディアン)。

  • [32 ビット]HMAC アルゴリズムのキーの長さ (バイト単位、ビッグ エンディアン)。 (現在、キー サイズは常にダイジェスト サイズと一致します)。

  • [32 ビット]HMAC アルゴリズムのダイジェスト サイズ (バイト単位、ビッグ エンディアン)。

  • EncCBC(K_E, IV, "")は、空の文字列入力を指定した対称ブロック暗号アルゴリズムの出力であり、IV は全ゼロ ベクトルです。 K_Eの構築を以下に説明する。

  • MAC(K_H, "")は、空の文字列入力を指定した HMAC アルゴリズムの出力です。 K_Hの構築を以下に説明する。

理想的には、 K_EK_Hにゼロのベクトルをすべて渡すことができます。 ただし、すべてのゼロ ベクトルのような単純または反復可能なパターンを使用することを妨げる演算 (特に DES と 3DES) を実行する前に、基になるアルゴリズムが弱いキーの存在をチェックする状況を回避したいと考えています。

代わりに、NIST SP800-108 KDF をカウンター モードで使用します ( NIST SP800-108、Sec. 5.1 を参照)。ゼロ長キー、ラベル、およびコンテキストを使用し、HMACSHA512 は基盤となる PRF として使用されます。 出力として | K_E | + | K_H | バイトを得てから、結果を K_EK_H に分解します。 数学的には、これは次のように表されます。

( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")

例: AES-192-CBC + HMACSHA256

たとえば、対称ブロック暗号アルゴリズムが AES-192-CBC で、検証アルゴリズムがHMACSHA256されている場合を考えてみましょう。 システムは、次の手順を使用してコンテキスト ヘッダーを生成します。

まず、 ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")します。ここで、指定したアルゴリズムごとに | K_E | = 192 bits| K_H | = 256 bits します。 これにより、次の例の K_E = 5BB6..21DDK_H = A04A..00A9 が生まれます。

5B B6 C9 83 13 78 22 1D 8E 10 73 CA CF 65 8E B0
61 62 42 71 CB 83 21 DD A0 4A 05 00 5B AB C0 A2
49 6F A5 61 E3 E2 49 87 AA 63 55 CD 74 0A DA C4
B7 92 3D BF 59 90 00 A9

次に、上記のように AES-192-CBC のEnc_CBC (K_E, IV, "")IV = 0*K_Eを計算します。

result := F474B1872B3B53E4721DE19C0841DB6F

次に、上記のK_Hを使用してMAC(K_H, "")とHMACSHA256を計算します。

result := D4791184B996092EE1202F36E8608FA8FBD98ABDFF5402F264B1D7211536220C

これにより、以下の完全なコンテキスト ヘッダーが生成されます。

00 00 00 00 00 18 00 00 00 10 00 00 00 20 00 00
00 20 F4 74 B1 87 2B 3B 53 E4 72 1D E1 9C 08 41
DB 6F D4 79 11 84 B9 96 09 2E E1 20 2F 36 E8 60
8F A8 FB D9 8A BD FF 54 02 F2 64 B1 D7 21 15 36
22 0C

このコンテキスト ヘッダーは、認証された暗号化アルゴリズム ペア (AES-192-CBC 暗号化 + HMACSHA256検証) の拇印です。 上記のコンポーネントは次のとおりです。

  • マーカー (00 00)

  • ブロック暗号キーの長さ (00 00 00 18)

  • ブロック暗号のブロックサイズ (00 00 00 10)

  • HMAC キーの長さ (00 00 00 20)

  • HMAC ダイジェスト サイズ (00 00 00 20)

  • ブロック暗号 PRP 出力 (F4 74 - DB 6F)

  • HMAC PRF 出力 (D4 79 - end)

CBC モード暗号化と HMAC 認証コンテキスト ヘッダーは、アルゴリズムの実装が Windows CNG によって提供されているか、管理された SymmetricAlgorithm 型と KeyedHashAlgorithm 型によって提供されるかに関係なく、同じ方法で構築されます。 これにより、異なるオペレーティング システムで実行されているアプリケーションは、OS 間でアルゴリズムの実装が異なる場合でも、同じコンテキスト ヘッダーを確実に生成できます。 (実際には、KeyedHashAlgorithm は適切な HMAC である必要はありません。キー付きハッシュ アルゴリズムの種類を指定できます)。

例: 3DES-192-CBC + HMACSHA1

まず、 ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")します。ここで、指定したアルゴリズムごとに | K_E | = 192 bits| K_H | = 160 bits します。 これにより、次の例の K_E = A219..E2BBK_H = DC4A..B464 が生まれます。

A2 19 60 2F 83 A9 13 EA B0 61 3A 39 B8 A6 7E 22
61 D9 F8 6C 10 51 E2 BB DC 4A 00 D7 03 A2 48 3E
D1 F7 5A 34 EB 28 3E D7 D4 67 B4 64

次に、上記のように 3DES-192-CBC のEnc_CBC (K_E, IV, "")IV = 0*K_Eを計算します。

result := ABB100F81E53E10E

次に、上記で示されたK_Hを用いてMAC(K_H, "")に対するHMACSHA1を計算します。

result := 76EB189B35CF03461DDF877CD9F4B1B4D63A7555

これにより、次に示すように、認証された暗号化アルゴリズム ペア (3DES-192-CBC 暗号化 + HMACSHA1検証) の拇印である完全なコンテキスト ヘッダーが生成されます。

00 00 00 00 00 18 00 00 00 08 00 00 00 14 00 00
00 14 AB B1 00 F8 1E 53 E1 0E 76 EB 18 9B 35 CF
03 46 1D DF 87 7C D9 F4 B1 B4 D6 3A 75 55

コンポーネントは次のように分解されます。

  • マーカー (00 00)

  • ブロック暗号キーの長さ (00 00 00 18)

  • ブロック暗号ブロック サイズ (00 00 00 08)

  • HMAC キーの長さ (00 00 00 14)

  • HMAC ダイジェスト サイズ (00 00 00 14)

  • ブロック暗号 PRP 出力 (AB B1 - E1 0E)

  • HMAC PRF 出力 (76 EB - end)

Galois/Counter Mode の暗号化と認証

コンテキスト ヘッダーは、次のコンポーネントで構成されます。

  • [16 ビット]値 00 01 は、"GCM 暗号化 + 認証" を意味するマーカーです。

  • [32 ビット]対称ブロック暗号アルゴリズムのキー長 (バイト単位、ビッグ エンディアン)。

  • [32 ビット]認証された暗号化操作中に使用される nonce サイズ (バイト単位、ビッグ エンディアン)。 (このシステムでは、これは nonce サイズ = 96 ビットで固定されています)。

  • [32 ビット]対称ブロック暗号アルゴリズムのブロック サイズ (バイト単位、ビッグ エンディアン)。 (GCM の場合、これはブロック サイズ = 128 ビットで固定されます)。

  • [32 ビット]認証された暗号化関数によって生成される認証タグのサイズ (バイト単位、ビッグ エンディアン)。 (このシステムでは、これはタグ サイズ = 128 ビットで固定されています)。

  • [128 ビット] Enc_GCM (K_E, nonce, "")のタグ。これは、空の文字列入力を指定した対称ブロック暗号アルゴリズムの出力であり、nonce は 96 ビットの全ゼロ ベクトルです。

K_E は、CBC 暗号化 + HMAC 認証シナリオと同じメカニズムを使用して派生します。 ただし、ここでは K_H がないため、基本的に | K_H | = 0があり、アルゴリズムは次の形式に簡素化されます。

K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")

例: AES-256-GCM

まず、K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")| K_E | = 256 bitsします。

K_E := 22BC6F1B171C08C4AE2F27444AF8FC8B3087A90006CAEA91FDCFB47C1B8733B8

次に、上記のように AES-256-GCM の Enc_GCM (K_E, nonce, "") の認証タグ nonce = 096K_E を計算します。

result := E7DCCE66DF855A323A6BB7BD7A59BE45

これにより、以下の完全なコンテキスト ヘッダーが生成されます。

00 01 00 00 00 20 00 00 00 0C 00 00 00 10 00 00
00 10 E7 DC CE 66 DF 85 5A 32 3A 6B B7 BD 7A 59
BE 45

コンポーネントは次のように分解されます。

  • マーカー (00 01)

  • ブロック暗号キーの長さ (00 00 00 20)

  • nonce サイズ (00 00 00 0C)

  • ブロック暗号ブロック サイズ (00 00 00 10)

  • 認証タグのサイズ (00 00 00 10)

  • ブロック暗号 (E7 DC - end)を実行する認証タグ。