web-dev-qa-db-ja.com

疑似ランダムジェネレーターが(エントロピープール)から初期化されていませんか?

RHEL5のマニュアルでは、/ dev/urandomは使い果たされるまでエントロピープールを使用し、フォールバック疑似ランダムアルゴリズムを使用するため、ブロックされないようになっています。

しかし、システムを調査したところ、(/dev/urandom)起動スクリプトに記載されているように、擬似ランダムジェネレータ/var/lib/random-seed/etc/rc.sysinitによって初期化されていることがわかりました。

ただし、/var/lib/random-seed自体は/dev/urandom o.Oからデータを取得します。ランレベル0(シャットダウン)またはランレベル6(再起動)に入るときの/etc/init.d/haltファイルスクリプトに記載されています。

したがって、/dev/urandomはエントロピープールを使用しませんか?!

私は混乱しています...どんな助けでもお願いします:)

5

/ dev/urandomはalwaysが可能な限り最もランダムな値を試行して返します。最悪の場合、暗号化を使用して、プール内のエントロピーの最後のビットを「ストレッチ」して、要求を満たします。対照的に、/ dev/randomは、エントロピープールが要求されたバイトを満たすのに十分になるまでブロックするので、/ dev/randomは、よりランダムな値を保証します 。ただし、/ dev/randomは、エントロピーストアが要求されたバイトを埋めるのに十分な大きさになるまでブロックします。これは、ほとんどすべての用途で受け入れられません。エントロピープールがいっぱいの場合、/ dev/urandomと/ dev/randomはidenticalになります。

rc.sysinitのシャットダウン時/dev/urandomから512バイトをコピーします。この時点では、マシンがしばらくオンになっている可能性が高いため、エントロピープールがいっぱいになる可能性があります。このファイルには、おそらくエントロピープールの純粋なチャンクが存在します。ただし、エントロピープールがいっぱいでない場合は、何もないよりも何かを持っている方がよい(さらに悪いことに、シャットダウンする前にエントロピープールが十分にいっぱいになるまでブロックする)。

Linuxシステムでは、エントロピープールが起動時に入力されることが非常に重要です。このニーズを満たすために、シャットダウンアクションはエントロピープールをディスクに保存することであり、起動はこのエントロピープールをブートプロセスの非常に早い段階で再ロードすることです。 Linuxシステムでは、ASLRされたメモリ位置とTCPシーケンス値は、このエントロピープールを使用して計算されます。プールがフラッシュされた場合、起動のたびにデーモンプロセスのメモリスペースレイアウトは非常にランダムではなく、SMTPデーモンのようなプロセスでは、バッファオーバーフローを介してより簡単に悪用される。これはMITM攻撃に対する感受性にも影響します。これは、攻撃者がTCP 3ウェイハンドシェイクを完了するために必要なTCPシーケンス値を予測するのが容易になるためです。

復元できないLinuxディストリビューションが起動時のエントロピープールではない場合、その脆弱性を報告する必要があります

さらに情報が必要な場合は、 random.c のコードコメントを読んでみてください。

6
rook

エントロピープールでPRNGがどのように機能するかを詳細に説明して、他の回答を補足しましょう。現在のLinux実装では複数のプールを使用しているため、これは少し単純化しすぎです。しかし、それはスキームがどのように機能するかの基本的な考えをあなたに与えるのに役立つはずです。

まず、3つの主要な部分が含まれています。

  1. エントロピープール。これは基本的には単なるバイトの配列です。システムの重要な目標は、攻撃者がこれらのバイトを知らないようにすることです。

  2. PRNG。これは、ランダム出力を生成するためにエントロピープールで動作するアルゴリズムコンポーネントです。

  3. エントロピープローブのコレクション。これらは、ネットワークやディスクのアクティビティなどのランダム性を「マイニング」して、エントロピープールに追加します。

PRNGは、エントロピープールを「引き出し」ます。正確なアルゴリズムは複雑ですが、基本的な考え方は、プールで暗号化された安全なハッシュ演算を実行し、一部のハッシュを出力して、一部のハッシュはプールに戻されます(現在のLinuxコードでは、実際には2つのSHA1操作を使用しています)。

プローブはエントロピープールを「満たす」。正確なアルゴリズムはさらに複雑です(ツイストGFSR)。ただし、基本的な考え方は、プールが混合され、プローブからのさまざまな情報がXORされてプールに入れられることです。

さらに、システムはプール内のエントロピーの量を測定し続けます。ランダムな出力を生成するとプールが「枯渇」し、エントロピーを追加するとプールが「満たされる」と想定しています。これは真実であるという理論的な意味がありますが、事実上それは問題ではありません。

たとえば、2,048バイトのプールと、プールの内容について何も知らない攻撃者を想定します。そして、プールからの出力が8バイトであると想定します。理論的には、2の64分の1の可能な初期条件を除くすべてを除外し、正確な8バイトを生成する条件のみを残します。しかし、攻撃者がその情報を使用する方法は知られていないか、考えられさえしていません。

エントロピーを追加せず、PRNGからの出力を1GBにすると、攻撃者はプールの初期状態を把握し、プールからの次の出力を予測するために必要なすべての情報を入手できます。問題は、2 ^(8 * 2048)の可能性のあるすべての初期条件を試す以外にそれを行う既知の方法がないことです。

実際には、2つの攻撃のみが可能です。

  1. 追加されたプールの内容を推測します。たとえば、128ビットを超える未知のデータがプールに混在している場合、これは失敗します。攻撃者は2 ^ 128以上の組み合わせを試すことはできません。

  2. 後でプールの内容を推測します。しかし、これには全体プールを推測する必要があります。

要するに、アルゴリズムに欠陥がない限り、プールからの出力はプールの内容に関する有用な情報を明らかにしません。攻撃者がallを予測または推測できない限り、プールから離れるまでプールに混入した情報は、プールから何が出てくるかを予測できません。 (もちろん、彼はプール自体を見ることができないと仮定します!)

5
David Schwartz

概要。混乱していることを非難しません。不正な情報が/dev/urandomにキャストされるという不正な情報がたくさんあります。

実際、/dev/urandomは安全です。短いバージョンは次のとおりです:/dev/urandomを使用し、それについて耳にする可能性のあるものは無視してください。 /dev/urandomは、強力で暗号品質の乱数が必要なほとんどすべての状況に適しています。 /dev/randomが正しい選択になることはほとんどありません。

技術的詳細。私の主張の根拠については、次の質問を参照してください。

そこにはたくさんのことが書かれており、私はそれを繰り返すつもりはありません。

ランダムシードファイル。1次近似では、ランダムシードファイルを無視できます。これは、/dev/urandomのセキュリティを確保するためにLinuxディストリビューションに存在する標準的なメカニズムです。アプリケーション開発者として、あなたはそれを心配する必要はありません。それは内部で起こります。あなたが知る必要があるのは、それが意図的に存在していること、そしてそれは正当な理由でそこにあり、それが有益であることです。

ああ、完全な説明が必要ですか?はい、こちらです。安全のために、/dev/urandomはどこかから少なくとも128ビット程度の真のランダムビットを取得する必要があります。 128ビット程度の真のエントロピーが得られると、それ以降は、出力がどれほど多くても、安全で暗号的に強力で予測不能な出力を期待できます。したがって、唯一の問題は、真のランダム性のこれらのビットがどこから来るのかということです。

Linuxカーネルには、真のランダム性を収集する多くのソースがあります。たとえば、割り込みのタイミング(たとえば、キーを押す、I/O)やその他の低レベルのものです。カーネルはこのランダム性を/dev/urandomが使用するプールに徐々に蓄積し、これらのソースが合計または128ビット程度の真のランダム性を生成すると、問題ありません。ただし、これらのソースは比較的低い速度でエントロピーを生成します。したがって、起動直後は、まだ十分なエントロピーを生成していない可能性があります。これに対処するために、Linuxディストリビューションには、再起動後に収集されたエントロピーを保持するメカニズムがあります。コンピューターをシャットダウンすると、コンピューターは/dev/urandomのエントロピープールからある程度のランダム性を引き出し(エントロピープールはおそらく適切なエントロピーを持っているので、これは十分に強いランダム性であるはずです)、ランダムシードファイルに保存します。 。次にコンピューターを起動したとき、ブート時にオペレーティングシステムがランダムシードファイルからエントロピーを取得し、/dev/urandomのプールに少なくとも128ビット程度のランダム性が確保されるようにします。したがって、コンピュータが十分なエントロピーをプールに蓄積すると、コンピュータを再起動した回数に関係なく、/dev/urandomの出力はそれ以降良好になります。

3
D.W.