web-dev-qa-db-ja.com

PHPでopenssl_random_pseudo_bytes()が非常にランダムであることを信頼できますか?

ユーザーごとにランダムなトークンを生成する必要のあるアプリケーションを見つけました。生成された各トークンが一意であることは非常に重要です。アプリケーションコードは次のとおりです。

$token = md5(open_ssl_random_pseudo_bytes(64));

正確にわかりませんopen_ssl_random_pseudo_bytesが機能するか、数値「64」が選択された理由、およびそれらのバイトがMD5ハッシュとどのように連携するか。

それで、このトークンは本当にどれくらいランダムですか?コードが10億回実行された場合、トークンは一意になりますか?

6
Boring person

open_ssl_random_pseudo_bytesは 暗号的に安全な疑似乱数ジェネレーター(CSPRNG) です。

簡単に言えば、これは、キー生成に適した、予測不可能な均一に分散されたシーケンスを生成できることを意味します。乱数ジェネレーターの完全な状態がわかっていても、攻撃者は以前に生成されたシーケンスを再作成できず、外部の観測者が将来のシーケンスを予測するために状態を推測することは不可能であるため、予測できないプロパティは重要です。

これは、真夜中を過ぎた秒数からシードを取得し、このシードに基づいて予測可能なシーケンスを生成する乱数ジェネレーターとは対照的です。この場合、攻撃者は、同じシードを使用して数値を生成するように独自のシステムを設定し、トークン値を推測して、それらを独自の悪意のある目的に使用することができます。

64バイトは512ビットのエントロピーを提供します。 MD5は128ビットのハッシュを出力するので、生成されるエントロピーが128を超える利点はありません。コードが10億回実行される場合、出力キースペースが2であるため、常に一意である可能性があります。128 (3.4 * 1038)。 MD5の衝突率は約2です。64 約180億です。

9
SilverlightFox

PHPバグ#70014 は最近のことであり、openssl_random_pseudo_bytes()の信頼性に影響を与えることに注意してください。

私は paragonie/random_compat に取り組んできました。これはrandom_bytes()をPHP 7からPHP 5に。サポートするフォールバックの1つはopenssl_random_pseudo_bytes()ですが、/dev/urandomから直接読み取ることができる場合は、代わりにそれを優先します。

7

Openssl_random_pseudo_bytesよりも random_bytes を使用することをお勧めします。

マニュアルから(php 7.x以降で利用可能):

random_bytes — Generates cryptographically secure pseudo-random bytes

サンプルコード(マニュアルからも):

 <?php

   $bytes = random_bytes(5);
   var_dump(bin2hex($bytes));

 ?>
2
MarcoZen

Openssl_random_pseudo_bytes( 71915 )には別のバグがあり、同じプロセスIDで複数回実行すると値が重複する可能性があります。 5.6.24で修正されたようです。

1
JW.