web-dev-qa-db-ja.com

対称鍵を生成するためのこの手法に深刻な問題はありますか?

ブルース・シュナイアーとニールス・ファーガソンの本から借りた、 Practical Cryptography というテクニックを使用しています。基本的に、それはこれに要約されます:


ボブはこれを行います:

pubk_A =アリスの公開鍵

エントロピー= PRNGからのバイト

暗号化されたエントロピー= RSA_Encryptpubk_A(エントロピ)

hashed_entropy =SHA2-512(エントロピー)

暗号化キーBA = hashed_entropy [0:32]
encrypt_nonceBA = hashed_entropy [32:48]
hmac_keyBA = hashed_entropy [48:64]

次に、ボブはencrypted_entropyをアリスに送信します。

次に、アリスはこれを行います:

privk_A =アリスの秘密鍵

エントロピー= RSA_Decryptprivk_A(encrypted_entropy)

hashed_entropy =SHA2-512(エントロピー)

暗号化キーBA = hashed_entropy [0:32]
encrypt_nonceBA = hashed_entropy [32:48]
hmac_keyBA = hashed_entropy [48:64]


これは、ボブからアリスへの通信に使用できるキーを生成するのに最適です。しかし、私は両方向で使用できるキーが必要です。私はこのようにアルゴリズムを変更することを考えていました:


ボブはこれをエントロピーで行います。

pubk_B =ボブの公開鍵

hashed_entropyBA =SHA2-512SHA2-256(pubk_A)||エントロピ)

暗号化キーBA = hashed_entropy [0:32]
encrypt_nonceBA = hashed_entropy [32:48]
hmac_keyBA = hashed_entropy [48:64]

hashed_entropyAB =SHA2-512SHA2-256(pubk_B)||エントロピ)

暗号化キーAB = hashed_entropy [0:32]
encrypt_nonceAB = hashed_entropy [32:48]
hmac_keyAB = hashed_entropy [48:64]

アリスは、encrypted_entropyを復号化してエントロピーを取得した後、同じことを自分の側で行うことができます。


ご覧のとおり、2セットのキーがあります。1つはボブからアリスへの通信に使用され、もう1つはアリスからボブへの通信に使用されます。

これに何か問題がありますか?私はどのようなセキュリティリスクを負っていますか?システムのセキュリティは、私が単に一方の当事者にナンスを少し調整させた場合よりも少ないですか、それとも多いですか?ラウンドトリップを追加せずにこの問題を処理するためのより良い方法はありますか?

4
Omnifarious

RSAを使用すると、選択したキーのサイズに基づいてn〜1バイトのエントロピーを安全に送信できます。したがって、2048ビットのRSAキーは、2047ビットのデータを暗号化できます。これは、キー/ノンス/ hmacのペアには十分すぎるほどです。メッセージダイジェスト関数を使用してエントロピーを拡張する必要があります回避ただし、RSAメッセージが埋め込まれない限り、十分なエントロピーがあります。最初のステップは、2047ビットのエントロピーを半分に分割し、結果をハッシュすることです。

hashed_entropyA=SHA2-512(entropy[0:1023])
hashed_entropyB=SHA2-512(entropy[1024:2047])

最初のセット:

encrypt_keyB = hashed_entropyB[0:32]
encrypt_nonceB = hashed_entropyB[32:48]
hmac_keyB = hashed_entropyB[48:64]

2番目のセット:

encrypt_keyA = hashed_entropyA[0:32]
encrypt_nonceA = hashed_entropyA[32:48]
hmac_keyA = hashed_entropyA[48:64]

結果は、2つの当事者が通信できるように、独立した強力な形式の鍵導出です。 システム全体が危険にさらされることなく、通信の片側が危険にさらされる可能性があります。多層防御、レイヤーのセキュリティ。

0
rook

あなたの特定の質問への回答:あなたが考えていることを達成するために彼らの計画を微調整するより簡単な方法があります。次の変更を加えることを除いて、本の内容に従ってください。

hashed_entropy = SHA2-512(0 || entropy) || SHA2-512(1 || entropy)

そのため、hashed_entropyには128バイトが含まれるようになりました。ここで、最初の64バイトをBob-> Alice方向に使用し(たとえば、本のようにキーとナンスを抽出する)、次の64バイトをAlice-> Bob方向に使用します(同様に、キーとナンスを抽出します)。

(ここでは、2つのバイトシーケンスを連結するために||と記述します。)

重要な注意事項:このスキームはボブを認証しません。相互認証が期待または必要な環境での使用には適していません。

高レベルのコメント:私はあなたが尋ねた特定の質問に答えようとしました。しかし、そこで立ち止まったら怠慢になります。あなたは正しい質問をしていると確信していますか?安全な(暗号化され、認証された)チャネルを構築する独自の方法を実装する必要がありますか?

Practical Cryptographyは素晴らしい本ですが、他にない限り、その本から取ったものであっても、カスタムデザインを使用するのはかなり気が進まないでしょう。選択。私の場合、最初に、TLSなど、十分に検討され、広く展開されている設計を再利用しようと真剣に試みます。それが私の要件を完全に満たしていない場合にのみ、私は何かカスタムを行うことを検討します。

私の批判は、実用的な暗号化の品質とは関係ありませんが、独自の設計と実装を行うとうまくいかない可能性のあるさまざまなことと関係があります安全なチャネル(たとえば、導入される可能性のある微妙な実装上の欠陥を含む)。

5
D.W.

必要なのは 鍵導出関数 :KDFは入力として「マスター鍵」(ここでは「エントロピー」文字列)を受け取り、対称暗号化に必要な数のバイトを生成します。単一のハッシュ関数呼び出しは、ハッシュ関数の出力サイズと同じ量の出力、つまりSHA-512の場合は64バイトを生成する粗KDFです。

多くのプロトコルにはカスタムKDFが含まれています。たとえば、 SSL/TLS では、「PRF」関数(セクション5で定義)は、 [〜#]内の基になるハッシュ関数(通常はTLS 1.2のSHA-256)を使用した構造です。 〜] hmac [〜#〜] 、繰り返し。別の標準KDFは PBKDF2 (セクション5.2)です。実際には、適切なストリーム暗号は適切なKDFになります(いくつかの適切なストリーム暗号については、 eSTREAMプロジェクト を参照してください)。

もう1つのオプションは、重要な資料の無駄を減らすことです。派生要素( "encrypt_key"、 "encrypt_nonce"、 "hmac_key")に付けた名前から、キー付きの整合性チェックを使用して、物事を対称的に暗号化することをお勧めします。対称暗号化とMACを一緒にするのは簡単な作業ではありません。多くの隠れた落とし穴があります。賢いのは、ブロック暗号に Authenticated Encryption モードを使用することです。 AEモードは、対称暗号化と整合性チェックを組み合わせ、独自のKDFを内部で処理します。 [〜#〜] eax [〜#〜] をお勧めします。このようなモードでは、「nonce」のみが必要です。これは、要件が1つしかないIVです。つまり、同じキーで2回使用することはできません。これにより、次のプロトコルが生成されます。

  • ボブは、a PRNG(少なくとも16バイト)からいくつかのバイト[〜#〜] m [〜#〜]を取得します)。
  • ボブはアリスの公開鍵で[〜#〜] m [〜#〜]を暗号化します。アリスはここで秘密鍵を使用して[〜#〜] m [〜#〜]を取得します。
  • アリスとボブの両方がSHA-256([〜#〜] m [〜#〜])を計算し、32バイトの文字列[〜#〜] k [〜#〜]
  • その後、ボブは[〜#〜] k [〜#〜][0..15]をEAXモードのキーとして使用して、メッセージをアリスに送信します。ナンスはメッセージカウンターです(最初のメッセージ用に1、2番目のメッセージ用に2など)。ナンスは、各メッセージに追加することも、アリスが暗黙的に知ることもできます(たとえば、「メッセージ」は、TCP接続)の連続したレコードです)。
  • 同様に、アリスは[〜#〜] k [〜#〜][16..31]をEAXモードのキーとして使用して、ボブにメッセージを送信できます。 。

必要な初期キーマテリアルは256ビットだけなので、単純なハッシュ関数の呼び出しで問題ありません。不格好なKDFは必要ありません。

しかし、実際には、それはSSLを再発明しているだけです。これは研究/教育目的には問題ありませんが、実際に展開することを意図したものについては、セキュリティの問題と実装のハードルがすでに(痛々しいほど)認識されている標準プロトコルに固執する必要があります。 SSLについて言及しましたか?

1
Thomas Pornin