2016-05-26 10 views
0

zu generieren Ich frage mich, welcher der beste Weg ist, hoch sichere Zufallszahl in Bereich 0-255 und darüber hinaus mit hoher Geschwindigkeit zu generieren. Es kommt zu mir, dass ich sicher die SecureRandom-Klasse verwenden muss, aber ich bin mir nicht sicher, ob ich .getInstance (SHA1PRNG) verwenden muss oder es besser ist, es ohne Arg-Konstruktor zuzulassen.Wie entscheiden, welche die sicherste Möglichkeit ist, Zufallszahlen in Java mit SecureRandom Klasse

Ich bin zwischen diesen zwei Möglichkeiten:

Erster Weg

public class RandomGenerator { 

    private static final String sha1prng = "SHA1PRNG"; 

    private final SecureRandom csprng; 
    private final byte[] bytes = new byte[1]; 

    public RandomGenerator() { 
     try { 
      csprng = SecureRandom.getInstance(sha1prng); 
     } catch (NoSuchAlgorithmException e) { 
      throw new RuntimeException(e); 
     } 
     csprng.nextBoolean(); 
    } 



    protected int generateByte() { 
     do { 
      csprng.nextBytes(bytes); 
     } while (bytes[0] == 0); 

     return ((byte)(bytes[0] & 0xff) + 256) % 256; 
    } 

    } 

Secondway:

public class SomethingThatNeedsRandomBytes { 

    private static final int NUMBER_OF_RANDOM_BYTES = ... ; 

    private final SecureRandom csprng; 

SomethingThatNeedsRandomBytes(SecureRandom csprng) { 
    if (csprng == null) 
    throw new IllegalArgumentException(); 

    this.csprng = csprng; 

    } 

    void doSomethingInvolvingRandomness() { 
    byte[] bytes = new byte[NUMBER_OF_RANDOM_BYTES]; 
    csprng.nextBytes(bytes); 
// Do something with random bytes here. 
    } 
    } 

Ich habe eine Menge von anderen Antworten in diesen Seiten gesehen und die meisten von ihnen nicht vorschlagen um SHA1PRNG zu benutzen und lassen Sie es default, aber auf der anderen Seite schlagen einige andere Antworten vor, NativePRNG zu verwenden (was ich nicht bevorzuge, da es nicht schnell ist) oder SHA1PRNG. Ich hätte gerne eine Rückmeldung darüber, welche der Möglichkeiten hohe sichere Zufallszahlen generiert und welche die schnellste ist.

Vielen Dank im Voraus.

+0

Sind Sie wirklich fragen, wie zu entscheiden, oder was nur die Antwort? – EJP

+0

@EJP Ich möchte wissen, wie man das entscheidet? Ok, ich kann Speed-Performance-Test mit Benchmarking oder System.nanoTime() tun, aber ich weiß nicht, wie zu entscheiden, welche sicherer ist –

Antwort

0

Mit einem leeren Konstruktor wählt SecureRandom den ersten registrierten Sicherheitsprovider aus, der einen SecureRandom-Algorithmus unterstützt. Wenn keine vorhanden ist, wird SHA1PRNG standardmäßig verwendet. Dies hängt vom System ab. Wenn Ihre Anwendung in verschiedenen Umgebungen ausgeführt wird, sollten Sie den Algorithmus im Konstruktor angeben. Um die Reihenfolge der Sicherheitsanbieter für Secure abzurufen, können Sie das folgende laufen:

import java.security.Security; 
import java.security.Provider; 
import java.security.Provider.Service; 

for (Provider provider : Security.getProviders()) { 
    for (Service service : provider.getServices()) { 
     if (service.getType().equals("SecureRandom")) { 
      System.out.println(service.getAlgorithm()); 
     } 
    } 
} 

Die Implementierung von NativePRNG ist abhängig vom Betriebssystem, aber in der Regel verwendet Entropie erzeugt durch Hardware- oder Betriebssystemereignisse Zufallswerte zu erzeugen. Oft muss dies darauf warten, dass Entropie generiert wird, bevor ein Wert zurückgegeben werden kann. In absoluten Zahlen ist dies sicherer als SHA1PRNG; jedoch ist es praktisch unwahrscheinlich, dass Sie den Unterschied bemerken. Wenn die Geschwindigkeit des Algorithmus für die Anwendung wichtig ist, ist SHA1PRNG im Allgemeinen schneller als NativePRNG, und beide Algorithmen liefern ausreichend zufällige Werte für kryptografische Operationen. Es sollte angemerkt werden, dass für Anwendungen wie Passwort-Hashing typischerweise ein langsamerer Algorithmus bevorzugt wird.

Siehe: https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html#SecureRandom--

+0

D.Holland Ich schätze es wirklich. Es war sehr hilfreich für mich. Ich benutze ShamirSecretSharing-Schema, in dem es für jedes Byte der Datei angewendet werden muss und wenn die Datei sagen einige Gb dann NativePRNG verwenden wird, werde ich viel Zeit brauchen, um die Datei zu teilen und zu rekonstruieren. Meine Operationen basieren auf GF (256), was der effizienteste ist, und ich habe die Hornersche Regel verwendet, um das Polynom auszuwerten, das die Anzahl der Multiplikationen reduziert. Also, was glaubst du ist sicher genug, wenn ich SHA1PRNG benutze? Der Grund, warum ich frage, ist, weil ich keinen Weg finde, zu beweisen, welcher mehr gesichert ist –