8

に関する多くの記事をフォローした後、JavaでのSecurityAPISecureRandomの使用に疑問が生じました。SecureRandom以下の例では。

public class SecureRandomNumber {
public static void main(String[] args) throws NoSuchAlgorithmException {

    TreeSet<Integer> secure = new TreeSet<Integer>();
    TreeSet<Integer> unSecure = new TreeSet<Integer>();
    SecureRandom sr = new SecureRandom();
    byte[] sbuf = sr.generateSeed(8);
    ByteBuffer bb = ByteBuffer.wrap(sbuf);
    long d = bb.getLong();
    sr.setSeed(d);

    Random r = new Random();
    r.setSeed(System.nanoTime());
    for (int k = 0; k < 99999; k++) {
        int i = sr.nextInt();
        if (!secure.add(i)) {
            System.out.println("Repeated Secure Random Number");
        } else {
//              System.out.println("************Unique***********");
        }
        int j = r.nextInt();

        if (!unSecure.add(j)) {
            System.out.println("Repeated UnSecure Random Number");
        }
    }
}

}

SecureRandomこのプログラムを実行すると、ほぼ同じ結果が得られるため、を使用しても追加のメリットはありません。

私がここで正しいことをしているのかどうか誰かに知らせてもらえますか?

4

3 に答える 3

17

あなたは一般的に乱数についての一般的な誤解の犠牲になっています:ランダムなシーケンスは、そのシーケンスで数字を繰り返すことができないという意味ではありません。それどころか、それは高い確率で行わなければなりません。その誤解は、実際には、人間によって生成された「ランダムな」シーケンスと実際のシーケンスを区別するために使用されます。人間によって生成された0と1の「ランダムな」シーケンスは、おそらく次のようになります。

0、1、0、1、1、0、1、0、0、1、0、1、0、...。

実際のランダムシーケンスは、同じ数を2回以上繰り返すことを躊躇しませんが、良い例は、統計的検定でも繰り返しを探すことです。

どちらの種類のジェネレーターにも、優れた「統計的特性」があります。

また、暗号的に安全な乱数がどういうわけか「はるかにランダムな」値を生成するというのもよくある誤解です。それらの統計的確率はおそらくほとんど同じであり、両方ともそれらの標準的な統計的検定で非常にうまく機能します。

どこで使用するか

したがって、実際には、PRNGを選択するか、暗号的に安全なPRNG(CSPRNG)を選択するかによって、何をしたいかによって異なります。「通常の」PRNGは、モンテカルロ法などのシミュレーション目的には完全に適しています。CSPRNGの追加の利点は、予測不可能なことです。CSPRNGは「より多くの」ことができるため、バニラPRNGよりもパフォーマンスが低下する可能性が高くなります。

「安全な」PRNGの概念は、その出力の次のビットを予測する機能と密接に関連していることを示すことができます。CSPRNGの場合、いつでもその出力の次のビットを予測することは計算上実行不可能です。もちろん、これは、シード値を秘密として扱う場合にのみ当てはまります。誰かがシードを見つけたら、全体を簡単に予測できるようになります。CSPRNGのアルゴリズムによってすでに生成されている値を再計算してから、次の値を計算するだけです。さらに、「次のビットの予測」の影響を受けないということは、CSPRNGの分布を実際のランダムな一様分布の分布と区別できる統計的検定がまったくないことを意味することを示すことができます。したがって、PRNGとCSPRNGには別の違いがあります。優れたPRNGは多くの統計的検定でうまく機能しますが、すべてのテスト。

どこで使用するかという経験則

  • CSPRNGは、外部から機密情報を推測されたくない「敵対的な」環境で使用します(セッションID、実際のお金が勝ち負けするオンラインポーカーなど)。
  • そして、良い統計的特性を必要とするが予測可能性を気にしない慈悲深い環境でのPRNG(モンテカルロシミュレーション、シングルプレーヤーポーカー対コンピューター、コンピューターゲーム一般)-つまり、お金を稼ぐことはできません。誰かがそれらの乱数をうまく予測できれば失われます。
于 2012-06-19T12:53:58.557 に答える
5

安全なアルゴリズムと安全でないアルゴリズムでは、ほとんど同じ結果が得られることがよくあります。出力にセキュリティ上の欠陥を検出することはできません。ピッキングできないロックのあるドアと簡単にピッキングできるロックのあるドアはほとんど同じように見え、ハンドルを回すだけではどちらも開きません。これが、安全なコードを記述し、暗号化や認証などを処理することが、設計、開発、特にテストに特化した技術を使用したプログラミングの領域である理由の1つです。

于 2012-06-19T10:45:12.190 に答える
2

SecureRandomは、毎回一意の乱数を保証するわけではありません。これは、前の数値が与えられた場合、次の乱数を予測できないことを保証するだけです。したがって、基本的に、あなたは間違った答えを探しています。

サイコロの例を使ってみましょう。安全なランダムを使用することは、通常のアンロードされたサイコロを使用することに似ています。すべてのサイコロの目は、前のサイコロの目から独立しています。安全でないランダムは、前のダイスロールを使用して次の結果を決定します。(したがって、前のロールが6であることがわかっている場合は、次のサイコロの目を予測できます)。

したがって、基本的に、ユーザー/ハッカー/管理者などが、前の乱数のリストが与えられた場合にどの番号が表示されるかを予測できる場合、それがアプリケーションにとって問題であるかどうかを判断する必要があります。(ほとんどの場合、これは問題になります)。乱数を使用してWebページに表示するランダムなものを選択するだけの場合は、通常のランダムで問題ありません。セキュリティ、ゲーム、または取引に乱数を使用する場合は、SecureRandomを使用するのが最適です。

よくわかりませんが、SecureRandomを使用するとオーバーヘッドがわずかに増加すると思います。したがって、ランダムはわずかに高速です。しかし、ほとんどの場合、この速度の向上は、安全でない乱数ジェネレーターの不安定さを悪用した場合に、潜在的な問題が続く価値はありません。

于 2012-06-19T10:55:18.907 に答える