Java-Anwendungen können und sollten die Klasse java.security.SecureRandom verwenden , um mithilfe eines kryptografisch starken Pseudozufallszahlengenerators ( CSPRNG ) kryptografisch starke Zufallswerte zu erzeugen . Die Standard-JDK-Implementierungen der Klasse java.util.Random werden nicht als kryptografisch stark angesehen.
Unix-ähnliche Betriebssysteme verfügen über /dev/random
eine spezielle Datei, die Pseudozufallszahlen bereitstellt , die auf Umgebungsgeräusche zugreifen, die von Gerätetreibern und anderen Quellen gesammelt wurden. Es wird jedoch blockiert, wenn weniger Entropie verfügbar ist als angefordert . /dev/urandom
In der Regel wird nie blockiert, selbst wenn der Startwert des Pseudozufallszahlengenerators seit dem Start nicht vollständig mit Entropie initialisiert wurde. Es gibt noch eine dritte spezielle Datei, /dev/arandom
die nach dem Booten blockiert, bis der Startwert mit genügend Entropie sicher initialisiert wurde, und dann nie wieder blockiert.
Standardmäßig setzt die JVM die SecureRandom- Klasse mit /dev/random
, daher kann Ihr Java-Code unerwartet blockieren . Die Option -Djava.security.egd=file:/dev/./urandom
im Befehlszeilenaufruf zum Starten des Java-Prozesses weist die JVM an, /dev/urandom
stattdessen zu verwenden .
Das Extra /./
scheint die JVM dazu zu bringen, den SHA1PRNG-Algorithmus zu verwenden, der SHA-1 als Grundlage für den PRNG (Pseudo Random Number Generator) verwendet. Es ist stärker als der NativePRNG-Algorithmus, der bei /dev/urandom
Angabe verwendet wird.
Schließlich gibt es einen Mythos, der /dev/urandom
ein Pseudozufallszahlengenerator, ein PRNG, /dev/random
ist , während er ein "wahrer" Zufallszahlengenerator ist . Dies ist einfach nicht wahr, beide /dev/random
und /dev/urandom
werden von demselben CSPRNG (kryptografisch sicherer Pseudozufallszahlengenerator) gespeist. Nur das Verhalten, wenn ihrem jeweiligen Pool die Entropie ausgeht, unterscheidet sich nach einigen Schätzungen: /dev/random
Blöcke, während /dev/urandom
dies nicht der Fall ist.
Was ist mit der Entropie, die zur Neige geht? Es spielt keine Rolle.
Es stellt sich heraus, dass „zufällig aussehen“ die Grundvoraussetzung für viele unserer kryptografischen Bausteine ist. Und wenn Sie die Ausgabe eines kryptografischen Hashs nehmen, muss dieser nicht von einer zufälligen Zeichenfolge zu unterscheiden sein, damit die Chiffren ihn akzeptieren. Dies ist der Grund für die Verwendung des SHA1PRNG-Algorithmus, da er eine Hash-Funktion und einen Zähler zusammen mit einem Startwert verwendet.
Wann soll angewendet werden?
Immer würde ich sagen.
Quellen:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
EDIT 04/2020:
In einem Kommentar wird eine Änderung des Verhaltens der SecureRandom- Klasse in Java 8 erwähnt.
SHA1PRNG und NativePRNG wurden behoben, um die Eigenschaften der SecureRandom-Seed-Quelle in der Datei java.security ordnungsgemäß zu berücksichtigen. (Die obskure Problemumgehung mit file: /// dev / urandom und file: / dev /./ urandom ist nicht mehr erforderlich.)
Dies wurde bereits durch die Tests hervorgehoben, auf die im obigen Abschnitt Quellen verwiesen wird. Das Extra /./
ist erforderlich, um den von SecureRanom in Java 8 verwendeten Algorithmus von NativePRNG auf SHA1PRNG zu ändern.
Ich habe jedoch einige Neuigkeiten, die ich gerne teilen möchte. Gemäß der JEP-273 , da Java 9 die Secure Klasse implementiert die drei Determinis Zufallsbitgenerators (DRBG) Mechanismen beschrieben in NIST 800-90Ar1 . Diese Mechanismen implementieren moderne Algorithmen, die so stark sind wie SHA-512 und AES-256.
Das JDK hatte zwei Arten von SecureRandom- Implementierungen:
- Eine davon ist plattformabhängig und basiert auf nativen Aufrufen oder Betriebssystemgeräten wie dem Lesen
/dev/{u}random
unter Unix oder der Verwendung von CryptoAPI unter Windows. Die neuesten Versionen von Linux und Windows unterstützen DRBG bereits, ältere Versionen und eingebettete Systeme jedoch möglicherweise nicht .
- Die andere Art ist eine reine Java-Implementierung, die eine ältere SHA1-basierte RNG-Implementierung verwendet, die nicht so stark ist wie die von genehmigten DRBG-Mechanismen verwendeten Algorithmen.
In der Zwischenzeit lautet das Java 13 Security Developer's Guide noch
Wenn unter Linux und macOS das Entropieerfassungsgerät in java.security auf file:/dev/urandom
oder file:/dev/random
eingestellt ist, wird NativePRNG SHA1PRNG vorgezogen. Andernfalls wird SHA1PRNG bevorzugt.
Um zu verdeutlichen, wie die neuen DRBG-Mechanismen mit den vorherigen PRNGs zusammenspielen, führe ich mit AdoptOpenJDK (Build 13.0.2 + 8) einige Tests unter macOS (Darwin) durch. Hier sind die Ergebnisse:
Datei: / dev / random
Reihenfolge der Präferenzen für Anbieter:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
Datei: / dev / urandom
Präferenzreihenfolge für Anbieter:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
Datei: / dev /./ urandom
Reihenfolge der Präferenzen für Anbieter:
SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG
Fazit:
Ich würde empfehlen, -Djava.security.egd=file:/dev/./urandom
diese Option zu verwenden , um sicherzustellen, dass die stärkste verfügbare SecureRandom- Implementierung unabhängig von der verwendeten Plattform genutzt wird, ohne dass der Code unerwartet blockiert wird.
/dev/urandom
wählt NativePRNG aus, das von gespeist wird,/dev/urandom
während/dev/./urandom
SHA1PRNG/dev/urandom
bei Verwendung von Java 8 aufgegriffen wird (ebenfalls gespeist von ). Ab Java 9 hat DRBG Vorrang, wenn die/dev/./urandom
Quelle angegeben wird.Dies ist nicht mehr erforderlich, wenn Sie JDK 8 oder höher verwenden
Das Problem wurde von Java behoben und hier sind einige Links
Gliederung
Für weitere Informationen (Suche nach Zufall auf der Seite):
https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html
https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
quelle
Dies hängt mit dem Unterschied zwischen Linux
/dev/random
und/dev/urandom
Zufallszahlengenerator zusammen.Aus diesem Link entnommen
Zur Beantwortung Ihrer Frage
Basierend auf dem obigen Link ist dies etwas Einzigartiges für Java-Versionen 5 und folgende, das sich aus Problemen mit / dev / urandom auf Linux-Systemen im Jahr 2004 ergab.
quelle