Wofür ist die Option java.security.egd vorgesehen?

22

In einem Projekt, an dem ich arbeite, wird die Anwendung mit einem ähnlichen Befehl gestartet:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

Ich habe die java.security.egdOption noch nie gesehen . Wenn Sie ein wenig suchen, wird es anscheinend verwendet, um die Zufallszahlengenerierung in einer Java-Anwendung zu konfigurieren.

Ist es richtig? Wann soll angewendet werden?

Davioooh
quelle

Antworten:

29

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/randomeine 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/urandomIn 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/arandomdie 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/./urandomim Befehlszeilenaufruf zum Starten des Java-Prozesses weist die JVM an, /dev/urandomstattdessen 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/urandomAngabe verwendet wird.

Schließlich gibt es einen Mythos, der /dev/urandomein Pseudozufallszahlengenerator, ein PRNG, /dev/randomist , während er ein "wahrer" Zufallszahlengenerator ist . Dies ist einfach nicht wahr, beide /dev/randomund /dev/urandomwerden von demselben CSPRNG (kryptografisch sicherer Pseudozufallszahlengenerator) gespeist. Nur das Verhalten, wenn ihrem jeweiligen Pool die Entropie ausgeht, unterscheidet sich nach einigen Schätzungen: /dev/randomBlöcke, während /dev/urandomdies 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}randomunter 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/urandomoder file:/dev/randomeingestellt 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/./urandomdiese 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.

dbaltor
quelle
1
Ab Java 8 ist die "obskure Problemumgehung" der zusätzlichen ./ im Dateinamen nicht mehr erforderlich. Sie können also einfach "/ dev / urandom" verwenden, siehe: docs.oracle.com/javase/8/docs / technotes / guide / security /…
Kamal
Vielen Dank für die Aktualisierung der Antwort (insbesondere zu den Änderungen in Java 9 und 13). Nach meinem Verständnis sollte ab Java 8 das Setzen des "Entropie-Erfassungsgeräts" auf / dev / urandom oder /dev/./urandom genau die gleichen Ergebnisse liefern, da sonst die Korrektur keinen Sinn ergibt. Aus Sicht des Betriebssystems verweisen diese auf dieselbe identische Datei, sodass Java nicht betroffen sein sollte (dies war vor dem Fix der Fall, aber das war ein Fehler, keine beabsichtigte Funktion). Daher Ihre Aussage "Das zusätzliche /./ ist erforderlich, um die PRNG-Auswahl zu beeinflussen." sollte ab Java 8 nicht mehr wahr sein.
Kamal
Danke @Kamal für deine Kommentare. Mein vorheriger Satz "PRNG-Auswahl" war nicht klar genug. Ich habe es umformuliert, um zu verdeutlichen, dass ich über den verwendeten Algorithmus spreche: NativePRNG oder SHA1PRNG. Die Verwendung von /dev/urandomwählt NativePRNG aus, das von gespeist wird, /dev/urandomwährend /dev/./urandomSHA1PRNG /dev/urandombei Verwendung von Java 8 aufgegriffen wird (ebenfalls gespeist von ). Ab Java 9 hat DRBG Vorrang, wenn die /dev/./urandomQuelle angegeben wird.
dbaltor
1

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

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.)

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

Venu Madhav
quelle
Ich glaube nicht, dass das richtig ist. Zum Hintergrund: tersesystems.com/blog/2015/12/17/… Die Fixes in Java 8 besagen nur, dass sie jetzt die SecureRandom-Seed-Source-Eigenschaften in der Datei java.security berücksichtigen. Aber standardmäßig enthält das noch: securerandom.source = file: / dev / random Die "obskure Problemumgehung" bezieht sich auf die zusätzliche ./ im Dateinamen, die auch in der akzeptierten (und am meisten bewerteten) Antwort hier erwähnt wird.
Kamal
Die "obskure Problemumgehung" war nur unter bestimmten Umständen erforderlich, siehe: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal
@Kamal Die von Ihnen geposteten Links beziehen sich auf Java 6 und früher.
Venu Madhav
Genau das ist der Punkt, der in Java 8 behoben wurde. Laut Fehlerbericht war nach Java 1.4.2 und bis zu 6 die "obskure Problemumgehung" (Hinzufügen der zusätzlichen ./ im Dateinamen) erforderlich auch in Java 7, sonst würde es in Java 8 nicht als behoben erwähnt. Die Einstellung von / dev / urandom anstelle von / dev / random ist jedoch weiterhin erforderlich, wenn Sie ein nicht blockierendes Gerät verwenden möchten.
Kamal
0

Dies hängt mit dem Unterschied zwischen Linux /dev/randomund /dev/urandomZufallszahlengenerator zusammen.

Aus diesem Link entnommen

Der Java- Fehler 6202721 besagt, dass java.security.SecureRandom / dev / random anstelle von / dev / urandom verwendet, auch wenn / dev / urandom angegeben ist, da / dev / urandom zu der Zeit (um 2004) nicht ordnungsgemäß funktionierte. Der Fehler wurde nie rückgängig gemacht, da / dev / urandom recht gut funktioniert. Daher müssen Sie es vortäuschen, indem Sie die Einstellung mit /dev/./urandom verdecken, um die Verwendung von SHA1PRNG anstelle von / dev / random zu erzwingen.

Zur Beantwortung Ihrer Frage

Wann soll angewendet werden?

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.

Ruelos Joel
quelle
In diesem Artikel ist wahrscheinlich ein Tippfehler enthalten, da in Java Bug 6202721 tatsächlich angegeben ist: "Dies ist ein Problem, wenn / dev / urandom ausgewählt wurde, weil / dev / random nicht ordnungsgemäß funktioniert." Daher ist Ihre Schlussfolgerung "resultiert aus Problemen mit / dev / urandom" falsch. In der akzeptierten Antwort finden Sie eine Erklärung zur Auswahl von / dev / urandom anstelle der Standardeinstellung (/ dev / random). In den meisten Fällen ist das eine gute Idee.
Kamal