openssl_random_pseudo_bytes()の予期しない動作により、暗号強度が致命的に失われます

すべての良い一日。



最近、プロジェクトの1つで、次の問題が発生しました。openssl_random_pseudo_bytes()関数が重複した擬似ランダムシーケンスを返しました。



それはありえないからです。 -この機能のドキュメントを読んだ人は誰でもわかります。 そして、はい、$ crypto_strongは定期的にTRUEを返しました。



それにもかかわらず、データベースへの挿入時の一意性エラーがバッチで注入され、ログが確認されました-日ごとに異なる間隔で32バイトのシーケンスが繰り返し生成されました。 調査には1か月かかりました。 今、私は99%の理由が見つかったと確信しています-しかし、Habrazhiteliが私の結論を確認または反論した場合、私は感謝します。







そして、3つの製品の機能を同時に組み合わせたものでした。



簡略化された状況は次のようになります-Apacheは、開始時にOpenSSLランダムジェネレーターを開始するPCPの最初のコピーを作成します。 そして、Apacheはフォークを作成して使用し、特にランダムジェネレーターの初期状態をコピーします。

ランダムジェネレーターもプロセスのPIDに関連付けられているため、問題はすぐには現れません。 LinuxではPIDの一般的な最大値は65536であるため、Webサーバーへのこの数のリクエストの後、生成された擬似ランダムシーケンスが繰り返され始めます。 より正確な技術的詳細は、上記で既に引用したOpenSLLナレッジベースの記事に最もよく見られます。



これらのOpenSSL関数は単にPCPから利用できないため、最良の推奨戦闘方法(フォークの後にRAND_seedを呼び出し、フォークの後にRAND_pollを呼び出す)がPCPに適用できないという事実によって、問題はさらに悪化します。



残念ながら、この問題については、既に言及したOpenSLLの記事を除き、ネットワーク上で適切な資料を見つけることができませんでしたが、Apache + PHP + OpenSSLの特定の束については説明していません。 しかし、openssl_random_pseudo_bytes()を暗号化RNGとして使用することを強く推奨する記事がたくさんあります。



しかし、王は裸です!



その結果、openssl_random_pseudo_bytes()の使用を単に放棄し、/ dev / urandomからの直接読み取りに切り替える必要がありました。 最も優れたソリューションではありませんが、このケースでは十分です。



著者は暗号化の分野の専門家ではなく、私の結論は不正確/不完全である可能性があり、openssl_random_pseudo_bytes()の使用に関する推奨事項の普及を考えると、問題は深刻であるため、専門家のすべてのコメントを間違いなく研究し、可能であれば修正/補足します基本的に間違っている)記事。 また、結論が確認された場合、PCPでスクリプトを開始するときに、PCPのドキュメントに追加して、RAND_seed / RAND_pollおよび/またはそれらの呼び出しを追加する提案を行う必要があります。



重要! Apacheはプリフォークモード(MPMプリフォーク)で動作するはずです。 問題がチェックされたPCPのバージョンは5.5.xですが、おそらく、openssl_random_pseudo_bytes()を含むすべてのバージョンで再生されます



PS私はsecurity@php.netで退会しました-ほぼ一ヶ月前。 答えも挨拶もありません。 または受信しませんでした。 または無視されます。 知りません

そこで、この記事をオンラインに戻します。



All Articles