10

このコードは安全ですか?

 SecureRandom randomizer = new SecureRandom(String.valueOf(new Date().getTime()).getBytes());

これは、安全なランダムのシードをインスタンス化する正しい方法ですか?

4

3 に答える 3

26

いいえ、SecureRandom(byte[])コンストラクターは避けてください。それは安全ではなく、携帯性もありません。

Windowsと他のオペレーティングシステムでは動作が異なるため、移植性はありません。

ほとんどのOSでは、デフォルトのアルゴリズムは「NativePRNG」です。これは、OSからランダムデータを取得し(通常"/dev/random")、指定したシードを無視します。

Windowsでは、デフォルトのアルゴリズムは「SHA1PRNG」です。これは、シードとカウンターを組み合わせて、結果のハッシュを計算します。

入力(ミリ秒単位の現在のUTC時間)の可能な値の範囲が比較的狭いため、これはあなたの例では悪いニュースです。たとえば、攻撃者が過去48時間にRNGがシードされたことを知っている場合、攻撃者はシードを2 28未満の可能な値に絞り込むことができます。つまり、エントロピーは27ビットしかありません。

一方、SecureRandom()Windowsでデフォルトのコンストラクターを使用した場合は、ネイティブCryptoGenRandom関数を呼び出して128ビットのシードを取得します。したがって、独自のシードを指定することにより、セキュリティが弱まります。

本当にデフォルトのシードをオーバーライドしたい場合(単体テストなど)、アルゴリズムも指定する必要があります。例えば

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("abcdefghijklmnop".getBytes("us-ascii"));

「 JavaSecureRandomでパフォーマンスの問題を解決する方法」も参照してください。
およびこのブログ投稿: http: //www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/

于 2012-09-03T16:35:48.827 に答える
2

SecureRandom自体をシードするのが最善だと思います。これは、作成直後にnextBytesを呼び出すことによって行われます(setSeedを呼び出すとこれを防ぐことができます)。

final byte[] dummy = new byte[512];
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.nextBytes(dummy);

デフォルトではないLinuxでも高速なノンブロッキング実装が保証されるため、SHA1PRNGを使用する必要があります。

于 2012-09-04T12:10:44.280 に答える
1

コードは、ランダマイザーのシードに指定されたシードを使用するだけではないため、かなり安全です。

単に使用するよりもはるかにランダムではありません。

SecureRandom randomizer = new SecureRandom();
于 2012-09-03T13:56:00.370 に答える