web-dev-qa-db-ja.com

乱数ジェネレーターが壊れやすいのはなぜですか?

乱数を生成するハードウェアコンポーネントは非常に単純なように思えます-センサーでハードウェアの小さな振動を測定するだけですよね?多分私は間違っているかもしれませんが、非常に高い精度で振動を測定した場合、推測できない乱数を簡単に生成できるようです。

ただし、私は暗号の初心者であり、ほとんど知りません。だから私は読んでいて 記事 は言う:

乱数ジェネレータを弱めるために、それほど洗練されている必要はありません。これらの発電機はすでに驚くほど壊れやすく、故障したときにそれを検出することは非常に困難です。 Debianのメンテナは、誤ったコードのクリーンアップがOpenSSLの有効なエントロピーを16ビットにまで減らした2008年に、この点を美しく示しました。実際、RNGは非常に脆弱であるため、ここでの課題はRNGを弱めることではありません。キーボードを使ったばかはそれを行うことができます。実装を他の誰に対しても脆弱にすることなくそうしています。

乱数生成がどのように「壊れやすい」かについて、いくつかの重要な詳細を見逃していることは確かです。誰かが説明できますか?

71
john doe

ハードウェアとソフトウェアのRNG

あなたが最初に言及するのはハードウェアのノイズ源です。いくつかの準安定現象の高精度測定は、予測できないデータを生成するのに十分です。これは、逆バイアスのツェナーダイオード、リングオシレーター、ADC、またはガイガーカウンターを使用して行うことができます。キーストローク間のタイミングのナノ秒レベルの遅延を測定することもできます。これらのノイズ源は、ハードウェア自体が故障し始めると故障する可能性があります。たとえば、高電圧で逆方向に動作するように特別に設計されていない場合、トランジスタは故障する可能性があります。これらの手法にはさまざまなレベルの脆弱性がありますが、引用したテキストで説明されているものではありません。

2つ目のタイプのRNGは、疑似乱数ジェネレータ(PRNG)と呼ばれるソフトウェアRNGです。*)。これは、暗号化キーのようなseedを取り、それを無限のデータストリームに展開するアルゴリズムです。アルゴリズムが開始した秘密のランダムシードの知識がなければ、データを予測したり、純粋なランダム性とは別に伝えたりできないようにします。この場合、PRNGは純粋なソフトウェアに実装されているので、これを壊すことは、バグをコードに導入するだけです。これは、あなたが引用したテキストが話していることです。それは単なるコードです。 fragile、アルゴリズムの意図された動作から逸脱するコードの変更が行われた場合、完全な失敗の危険を冒します。

A PRNGは、再利用された暗号化アルゴリズムと考えることができます。実際には、AESなどの暗号を使用して暗号的に安全なPRNGカウンター。暗号化キー(シード)が秘密である限り、出力を予測したりシードを発見したりすることはできません。このように考えると、コードの小さな、重要でない変更がどのようにできるかを理解しやすくなりますアルゴリズムのセキュリティを完全に破る。

ランダム性の収集

では、現代のデバイスは実際にどのようにランダム性を収集するのでしょうか?どこかのデータセンターで静かに稼働しているサーバーを見てみましょう。 TLSなどをサポートするには、真にランダムなストリームと区別できない、完全に予測不可能な大量のデータが必要です。専用のハードウェアノイズソースがない場合、ランダム性は内部から発生する必要があります。コンピューターは完全に決定論的であるように努めていますが、非決定論的デバイスからの多くの入力があります。入力...割り込み!

最新のハードウェアでは、割り込みは、ハードウェアが発行する信号であり、CPUにステータスの変化を警告します。これにより、CPUはすべてのハードウェアデバイスの更新を迅速にポーリングすることを回避でき、代わりに、デバイスが時間になると非同期でデバイスに警告することを信頼できます。割り込みが発生すると、信号を処理するために割り込みハンドラが呼び出されます。このハンドラはランダム性を得るのに最適な場所であることがわかりました!割り込みのナノ秒レベルのタイミングを測定すると、かなりのランダムさをすばやく得ることができます。これは、NICに到着するパケットからハードドライブから読み取られるデータまで、あらゆる種類の割り込みがトリガーされるためです。これらの割り込みソースの一部は、ハードディスクのように非常に非決定的です。アクチュエータの物理的な動きに依存するドライブ。

オペレーティングシステムによって十分なランダムビットが収集されたら、少なくとも128ビットの小さなシードを暗号で保護されたPRNGに供給して、疑似ランダムデータの無制限のストリームを生成できます。誰かが予測できない限り、正確に過去の割り込みが発生したとき、ナノ秒の精度で、シードを導出できず、将来の予測もできませんPRNG出力。これにより、出力はTLSキーに完全に適合します。

*セキュリティ指向のPRNGは暗号的に安全なPRNGまたはCSPRNGと呼ばれます。アプリケーションがCSPRNGを呼び出すときに通常のPRNGを使用すると、セキュリティが向上する可能性があります脆弱性。

75
forest

歴史的には、暗号化に適したハードウェアRNGはPCでは一般的に利用できませんでした。たとえば、 この質問によると AMDは数年前にサポートを追加しただけなので、今日でもソフトウェアベンダーは単純に想定できませんそれが利用可能になること。これがおそらく、OpenSSL(引用で述べたように)がソフトウェアRNGを使用していて、コードで見つかったバグに対して脆弱である理由です。

(コメントで広く議論されているように、標準のPCには、ソフトウェアRNGが利用できる多くの「エントロピーのソース」が含まれています-そして私はOpenSSLを使用していると思いますが、私はそれほど詳しくはありません-明らかにソフトウェアのバグが原因で、実際に発生したように、乱数が不良になる可能性があります。

ハードウェアRNGがバックドアされている可能性があることへの懸念 もあり、ハードウェアRNGをそのまま使用するのではなく、エントロピーの他のソースと組み合わせることができます。 (リンクされたハードウェアは、リンクされた記事でも言及されていますが、引用したビットから数段落上にあります。)

また、ハードウェアRNGは、質問が示唆するほど実装が簡単ではないことにも言及する必要があります。たとえば、単純な実装は、たとえば振動に基づいてランダムなビットを生成する場合、さまざまな物理的攻撃に対して脆弱になる可能性があります。 、誰かが超音波をそれに向けるとどうなりますか?理想的な条件下でさえ、生成されたビットを暗号化の使用に対して安全でなくする可能性がある結果に何らかのバイアスがある可能性があります。

そのため、実際の実装ではハードウェアノイズだけでなく 暗号化して処理 も使用します。しかし、その時点で、アルゴリズム(またはその実装)が意図的に妨害されているのか、それとも信じられているほど堅牢ではないのかという疑問に戻ります。

17
Harry Johnston

テストが難しいため

乱数ジェネレータが正しい形式で出力を生成することをテストするのは簡単ですが、統計的にランダムであるかどうかを判断することははるかに複雑であり、自動テストスイートに含まれる可能性はほとんどありません。あなたがそれを壊すならば、他の多くのコードははるかに明白になります。

暗号は正しい必要があります

一般に、コードが正しいことを確認することは困難です。多くのコードの節約の恩恵は、正確性エラーのほんの一部のみがセキュリティの脆弱性をもたらすことです。しかし、暗号化コード(乱数ジェネレーターを含む)を使用すると、多くの正確性エラーにより脆弱性が発生します。暗号コードは正しい、安全である必要があり、正しいことを確認することは困難です。

Debianのメンテナが重大なエラーを作りました

コードは実際にはそれほど脆弱ではありません。それを不安定にするためには、メンテナからの大きな失敗が必要でした。 chop out 行が、何も壊れていないという大まかなチェックだけで警告を生成するのは、かなりお粗末です。

編集:メンテナの責任だけではありませんでした、Angelのコメントを参照してください

12
paj28

ランダムジェネレーターの最も重要な側面の1つは、各ランダムビットの値が、それが生成する他のすべてのビットの値から完全に独立しているだけでなく、敵対者が観察または影響する可能性のある宇宙。残念ながら、そのプロパティは、多くの場合、実際に保証するのが最も難しいものの1つです。一般的にできる最善の方法は、宇宙内の他のものとの悪用可能な関係がありそうにない方法でビットを生成することです。

簡単な例として、RF送信機に集中している敵が乱数ジェネレーターに影響を与えることができたため、選択した特定のサンプルが95%の確率でサンプルを生成する場合、残りはそうする可能性が5%しかありません。そのようなジェネレータから128ビットを単に読み取り、それらを128ビットのキーに構築する場合、ブルートフォース攻撃に近いビットパターンに集中した攻撃者ジェネレーターに影響を与えるために使用されたものは、ジェネレーターがバイアスされていない場合よりも、迅速な成功の可能性がはるかに高くなります。ただし、ビットを1つずつ選択する代わりに、7ビットのグループを選択し、それらをxorこれを行うと、128ビットキーを生成する時間が7倍に増加しますが、攻撃者の影響は95/5から74/26に削減され、キーが最終的に攻撃者のビットパターンに近づく可能性が大幅に減少します。強制しようとしていた。

別の方法として、128個のランダムビットを生成し、何らかの方法でハッシュしてから、別の128個のランダムビットでXORすることを想定しました。これは896ではなく256ビットを生成するだけで済みますが、攻撃者がジェネレーターのバイアスを悪用することを非常に困難にします。最も可能性の高い95,000,000,000ビットの128ビットパターンを列挙しても、ハッシュの前に使用された128ビットのグループ、またはハッシュ値がxorされたグループと一致する可能性は約50%ですが、xorの後の​​最終的な分布exploitableバイアスまたは情報漏洩が発生する可能性はほとんどありません。

4
supercat

Linuxの/ dev/random、ChaCha20、RdRandなどの一般的に使用される安全なRNGは、多くの従来のケースでうまく機能します。しかし、彼らは馬鹿な証拠からはほど遠いです。起動時に乱数を生成するときにリアルタイムクロックを設定できないなど、おかしなことをするとします。それがRNGにどのように影響するかを理解していない場合、誰かがあなたの秘密鍵を持ち去る可能性があります。 1つの少量の非ランダム性が鍵生成などの暗号化プロトコル全体を危険にさらす可能性があるため、ここではエラーの余地はほとんどありません。

乱数ジェネレーターのナイーブ roll-your-own implementations またはハードウェアの物理的干渉に関する問題は良い議論を生みますが、次のような乱数ジェネレーターに関するニュースのほとんどの脆弱性あなたが言及したDebianの問題は、これらの問題が原因ではありません。私が繰り返し見た最大の問題は、実際には乱数ジェネレーターがシードされていないときにシードを生成するためのエントロピーの優れたソースがあると考えている開発者、ランダムに乱数ジェネレーターの状態を発見して悪用すること、または厳密なテストの欠如です。乱数ジェネレータ自体の。 TLSクライアントの0.75% 低エントロピーキーを使用している場合、NSAはキー生成をバックドアする必要はありません要約すると、開発者はいくつかの警告を無視しても無視し、RNGがどのアプリケーションでも機能すると想定します。

エントロピーとは何ですか、どこで入手できますか?

すべてのコンピュータープログラムは、同じ入力が与えられると同じ出力を生成するため、オペレーティングシステムまたはハードウェアのエントロピー(または予測できないデータ)のソースから読み取る必要があります。現在、RdRandコマンドのように、毎秒数十または数百MBのエントロピーを生成できるものがあります。ただし、1951年のFerranti Mark 1や1999年のIntel 82802 Firmware Hubなどのハードウェア乱数発生器を備えたデバイスは、2010年までは例外ではなく例外でした。

そのため、歴史的に、乱数ジェネレータは、人間の入力やコンピュータのタイミングなどの比較的遅いエントロピーソースに依存しており、レガシーシステムには、エントロピーの適切なソースを利用できる組み込み関数がほとんどない場合があります。たとえば、Linuxの/ dev/randomは、起動クロック時間、人間の入力デバイスのタイミング、ディスクタイミング、IRQタイミング、さらには他のスレッドによるエントロピープールの変更を使用する場合があります。

エントロピーを取得するこれらの標準的な方法は絶対確実ではないため、多くの点で乱数ジェネレータは壊れやすいです。これらのエントロピーソースを予測可能または制限するものはすべて、RNGを危険にさらします。次に例を示します。

状態の把握と再播種の欠如

多くの場合、RNGは/ dev/randomのようにすべての関数呼び出しで新しいエントロピーを取得しません。十分なエントロピーを十分に速く取得できない場合や、エントロピーソースを完全に信頼できない場合があります。そのため、代わりにRNGに既知のエントロピーソースがシードされ、そのシードから独立した値が生成されます。ただし、誰かがジェネレーターの内部状態を理解すると、物事がうまくいかず、 cloning smart card から スロットを不正にするmachine ラスベガス。

バッファオーバーフロー攻撃または同様の攻撃により、乱数ジェネレータの状態が明らかになる可能性があります。特にアルゴリズムが既知で可逆的である場合、迅速に計算できる場合、または平文が既知の場合は、ブルートフォース攻撃で状態を学習することも可能です。これは、 Windows XPDropbear SSHライブラリの問題の場合でした/ XorShift128 + in ChromeMesserneツイスターアルゴリズム 、その他多数。

これらの既知の状態の攻撃に対して高度な緩和策を要求すると、RNGが脆弱になります。既知の状態の攻撃を軽減する最善の方法は、脆弱なアルゴリズム(ほとんどの CSRNGs など)を使用しないことです。 この質問 は、優れたRNGを安全にする理由をより詳細に説明しています。ただし、CSRNGにも弱点がある場合があります(たとえば、 Linux 2.6.10カーネルのRNG脆弱性 )。そのため、多層防御では、乱数ジェネレーター(おそらくユーザーごとに1つ)に個別の状態を使用する、シードを頻繁に更新する、サイドチャネル攻撃やバッファーオーバーフローから保護するなどの緩和策が必要です。

開発者とユーザー間の非難

多くの場合、これらのRNGは壊れやすいものです。これは、ライブラリの開発者やOSの作成者が誰にでもできるシステムを設計できず、それを期待しているユーザーの間での制限のコミュニケーションが誤っているためです。たとえば、Linuxは、ユーザーに高遅延の/ dev/randomと潜在的に低エントロピーの/ dev/urandomのどちらかを選択するように強制します。別の例として、5.3より前のPHPは、mcrypt_create_iv()などのインターフェースを介したWindowsの強力なPRNGをサポートしていませんでした。7.0より前のバージョンには、優れたCSPRNGが組み込まれていませんでした。

検出の難しさ

乱数について議論するとき、人気のある議論のポイントがあります。真の乱数の場合、すべての可能性は等しく可能性があり、潜在的なパターンの数は無限です。では、どのようにしてシーケンスを実際に見て、ランダムではないと言えるのでしょうか。 (関連するディルバート

実際には、乱数でパターンを検出することは成熟していますが、不完全ではありますが、非ランダム性を検出できるかどうかに関する問題は、M.G。ケンドールとB.バビントン・スミスの1938年の論文。あなたができるは、特定の種類のパターンがランダムチャンスよりも大幅に出現する可能性が低いことを示しています。たとえば、カイ2乗検定によって決定されるしきい値を使用して、数字の1が他の数字よりも一般的であるかどうかを確認できます。これらのテストされたパターンが少なくともリモートで発生する可能性が高く、生成された数値の十分長いセットを確認している限り、誤検知の確率は低くなります。 いくつかの乱数ジェネレーターのいくつかの隠された問題は何年も検出されない可能性があります 、基本的な暗号解析を行ってから、 この質問 そして、あなたはあまりにも間違って行くことはできません。

ただし、設計者は攻撃者を過小評価することもあります(どのようにしてユーザーを予測するように想定されていましたか リバースエンジニアリングしてスロットマシンの時間を計りますか? )。さらに悪いことには、乱数ジェネレーターやエントロピー生成がエキスパートによって検査されないことがあり、PS3ファームウェアの署名 が定数 "random "出力

結局のところ、ここでの問題はほとんどのサイバーセキュリティの問題と似ています。乱数のプロトコル、要件、デバイスの非常に複雑なセットがあります。いつものように、複雑さを理解していなければ、理解している攻撃者に対して脆弱です。

1
Cody P