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

Lesezeit: 10 Minuten

Benutzer-Avatar
davioooh

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 noch nie gesehen java.security.egd Möglichkeit vor. Wenn Sie ein wenig suchen, scheint es verwendet zu werden, um die Generierung von Zufallszahlen in einer Java-Anwendung zu konfigurieren.

Ist es richtig? Wann soll es angewendet werden?

Benutzer-Avatar
DBALTOR

TL;DR

Wenn läuft Java 8 auf modernen Betriebssystemen mit Unterstützung für Deterministic Random Bit Generator (DRBG)würde ich die Verwendung empfehlen
-Djava.security.egd=file:/dev/urandom um zu vermeiden, dass der Code unerwartet blockiert wird. Wenn Sie sich nicht sicher sind, welches Betriebssystem verwendet wird, schlage ich vor, bei der ursprünglichen Empfehlung zu bleiben, nämlich:
-Djava.security.egd=file:/dev/./urandom

Wenn läuft Java11würde ich empfehlen, einfach zu verwenden
-Djava.security.egd=file:/dev/./urandom um sich zu vergewissern:

  1. das Stärkste nutzen SecureRandom Implementierung verfügbar (DRBG), unabhängig von der zugrunde liegenden Plattform
  2. vermeiden, dass der Code unerwartet blockiert wird (securerandom.source=file:/dev/urandom)

Lesen Sie weiter, um die Details zu erfahren.


Java-Anwendungen können und sollten verwenden java.security.SecureRandom Klasse zum Erzeugen kryptografisch starker Zufallswerte mithilfe eines kryptografisch starken Pseudozufallszahlengenerators (CSPRNG). Die standardmäßigen JDK-Implementierungen von java.util.Random Klasse gelten nicht als kryptografisch stark.

Unix-ähnliche Betriebssysteme haben /dev/random, eine spezielle Datei, die Pseudo-Zufallszahlen bereitstellt, die auf Umgebungsgeräusche zugreifen, die von Gerätetreibern und anderen Quellen gesammelt wurden. Jedoch, es blockiert, wenn weniger Entropie verfügbar ist als angefordert; /dev/urandom blockiert normalerweise nie, selbst wenn der Seed des Pseudozufallszahlengenerators seit dem Booten nicht vollständig mit Entropie initialisiert wurde. Es gibt noch eine 3. Spezialdatei, /dev/arandom die nach dem Booten blockiert, bis der Seed sicher mit genügend Entropie initialisiert wurde, und dann nie wieder blockiert.

Standardmäßig erstellt die JVM die SecureRandom Klasse verwenden /dev/randomdeshalb Ihr Java-Code kann unerwartet blockieren. Die Option -Djava.security.egd=file:/dev/./urandom im Befehlszeilenaufruf, der zum Starten des Java-Prozesses verwendet wird, teilt der JVM mit, dass sie verwendet werden soll /dev/urandom stattdessen.

Das Extra /./ scheint die JVM zu nutzen die SHA1PRNG-Algorithmus die SHA-1 als Grundlage des PRNG (Pseudo Random Number Generator) verwendet. Es ist stärker als der NativePRNG-Algorithmus, der wann verwendet wird /dev/urandom angegeben.

Schließlich gibt es einen Mythos /dev/urandom ist ein Pseudo-Zufallszahlengenerator, ein PRNG, während /dev/random ist ein „echter“ Zufallszahlengenerator. Das ist einfach nicht wahr, beides /dev/random und /dev/urandom werden von demselben CSPRNG (kryptographisch sicherer Pseudozufallszahlengenerator) gespeist. Nur ihr Verhalten unterscheidet sich: /dev/random blockiert, wenn seinem Zufallspool nach einer Schätzung die Entropie ausgeht, while /dev/urandom nicht.

Was ist mit Systemen mit niedriger Entropie? Es ist nicht so schlimm.

Es stellt sich heraus, dass „zufälliges Aussehen“ die Grundvoraussetzung für mehrere kryptografische Komponenten ist, wie z. B. kurzlebige Sitzungsschlüssel von Webservern. Und wenn Sie die Ausgabe eines kryptografischen Hashs nehmen, ist es nicht von einer zufälligen Zeichenfolge zu unterscheiden, sodass Chiffren es akzeptieren. Aus diesem Grund wird der SHA1PRNG-Algorithmus verwendet, da er eine Hash-Funktion und einen Zähler zusammen mit einem Seed verwendet.

Wann soll angewendet werden?

Immer, würde ich sagen.

Quellen:

https://gist.github.com/svrc/5a8acc57219b9548fe1

https://www.2uo.de/myths-about-urandom


EDIT 09/2020:

Ich habe dieses Update geändert, um die Tests widerzuspiegeln mit:
-Java 8 auf modernen Betriebssystemen
-Java 11, da es sich um die aktuelle LTS-Version (Long Term Support) handelt.

Ein Kommentar erwähnt eine Änderung am SecureRandom Klassenverhalten in Java 8.

SHA1PRNG und NativePRNG wurden korrigiert, um die Eigenschaften der SecureRandom-Seed-Quelle in der Datei java.security korrekt zu respektieren. (Der obskure Workaround mit file:///dev/urandom und file:/dev/./urandom ist nicht mehr erforderlich.)

Dies wurde bereits durch die Tests aufgezeigt, auf die im Abschnitt „Quellen“ oben verwiesen wurde. Das Extra /./ ist erforderlich, um den von verwendeten Algorithmus zu ändern SecureRandom in Java 8 von NativePRNG zu SHA1PRNG.
Ich stimme zu, dass NativePRNG sicherer ist als SHA1PRNG, aber nur, wenn es auf modernen Betriebssystemen ausgeführt wird. Ich habe daher mein Fazit entsprechend aktualisiert und nach oben verschoben.

Allerdings habe ich einige Neuigkeiten, die ich gerne teilen möchte. Gemäß der JEP-273seit Java 9 die SecureRandom Klasse implementiert die drei Deterministischer Zufallsbitgenerator (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 zuvor zwei Arten von SecureRandom Implementierungen:

  • Eines ist plattformabhängig und basiert auf nativen Aufrufen oder OS-Geräten wie dem Lesen /dev/{u}random unter Unix oder mit der CryptoAPI unter Windows. Die neuesten Versionen von Linux und Windows unterstützen bereits DRBG, aber ältere Versionen und eingebettete Systeme 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 Algorithmen, die von zugelassenen DRBG-Mechanismen verwendet werden.

Inzwischen die Entwicklerhandbuch für Java 11-Sicherheit liest sich noch

Unter Linux und macOS, wenn das Entropieerfassungsgerät in java.security auf eingestellt ist file:/dev/urandom oder file:/dev/random, dann wird NativePRNG gegenüber SHA1PRNG bevorzugt. Andernfalls wird SHA1PRNG bevorzugt.

Um zu verdeutlichen, wie die neuen DRBG-Mechanismen mit den vorherigen PRNGs zusammenspielen, habe ich einige Tests auf macOS (Darwin) mit AdoptOpenJDK (Build 11.0.7+10) durchgeführt. Hier sind die Ergebnisse:


-Djava.security.egd=file:/dev/random (Dies entspricht der Standardoption)
Standardalgorithmus: NativePRNG

Anbieter: SecureRandom.NativePRNG-Algorithmus von: SUN

-Djava.security.egd=file:/dev/urandom

Standardalgorithmus: NativePRNG

Anbieter: SecureRandom.NativePRNG-Algorithmus von: SUN

-Djava.security.egd=file:/dev/./urandom

Standardalgorithmus: DRBG

Anbieter: SecureRandom.DRBG-Algorithmus von: SUN


Schließlich der Punkt der Verwendung /dev/urandom als Quelle der Zufälligkeit bleibt auch bei der Verwendung moderner Betriebssysteme von größter Bedeutung, wie wir weiter lesen können dieser sehr interessante Beitrag:

Teilen /dev/random ist eine Herausforderung für jede Linux-Container-Technologie …
Das Problem der geringen Entropie auf virtualisierten Servern wird verschärft, weil … Linux-Container, die auf demselben Host laufen, um einen begrenzten Vorrat an Entropie konkurrieren. Diese Art von Problem wird manchmal als a bezeichnet stampfende Herde. Das /dev/random device ist eine knappe gemeinsam genutzte Systemressource, von der Linux-Container-Mandanten wahrscheinlich nicht bemerkt haben, dass sie sie teilen. Wenn sie alle versuchen, es gleichzeitig zu verwenden, verursachen sie effektiv einen Denial-of-Service auf einander.

Quellen:

https://www.openssl.org/blog/blog/2017/08/12/random/

  • Ab Java 8 entfällt der “obskure Workaround” des zusätzlichen ./ im Dateinamen, man kann also einfach “/dev/urandom” verwenden, siehe: docs.oracle.com/javase/8/docs/technotes/guides/security/…

    – Kamal

    27. April 2020 um 19:27 Uhr

  • 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 Festlegen des “Entropy Gathering Device” auf /dev/urandom oder /dev/./urandom genau die gleichen Ergebnisse liefern, da die Korrektur sonst keinen Sinn ergeben würde. Aus Sicht des Betriebssystems verweisen diese auf dieselbe identische Datei, sodass Java nicht beeinträchtigt werden sollte (vor dem Fix war dies 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 stimmen.

    – Kamal

    30. April 2020 um 11:23 Uhr


  • Danke @Kamal für deine Kommentare. Mein vorheriger Ausdruck „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/urandom wählt NativePRNG gespeist von /dev/urandom während /dev/./urandom nimmt SHA1PRNG auf (ebenfalls gefüttert von /dev/urandom) bei Verwendung von Java 8. Ab Java 9 hat DRBG Vorrang, wenn /dev/./urandom Quelle angegeben ist.

    – DBALTOR

    1. Mai 2020 um 18:46 Uhr


  • Nochmals vielen Dank DBALTOR. Ich würde dennoch empfehlen, den ursprünglichen Teil Ihrer Antwort “Das zusätzliche /./ scheint die JVM dazu zu bringen, das SHA1PRNG zu verwenden …” zu aktualisieren, um klarzustellen, dass es nur für Java 8 und früher gilt (Java 8 ist AFAIK immer noch beliebt). Auch die Art und Weise, wie es formuliert ist, lässt es klingen, als ob SHA1PRNG eine sicherere oder bessere Wahl wäre. Ich bin kein Experte, aber tersesystems.com/blog/2015/12/17/… und stackoverflow.com/a/27638413/279726 scheinen zu empfehlen, es Java zu überlassen, das geeignete PRNG zu bestimmen, anstatt SHA1PRNG zu erzwingen, was in bestimmten Fällen weniger sicher ist.

    – Kamal

    8. Mai 2020 um 19:35 Uhr

  • Vielen Dank. Java 17 ist jetzt LTS. Laut Spezifikation gelten Ihre Antworten für jvm 11 weiterhin für jvm 17 Specs: docs.oracle.com/en/java/javase/17/security/…

    – aholbreich

    9. Februar um 16:28 Uhr

Benutzer-Avatar
Ruelos Joel

Dies hängt mit dem Unterschied von Linux zusammen /dev/random und /dev/urandom Zufallszahlengenerator.

Daraus entnommen Verknüpfung

Java-Bug 6202721 gibt an, dass java.security.SecureRandom /dev/random anstelle von /dev/urandom verwendet, selbst wenn /dev/urandom angegeben ist, da /dev/urandom zu der Zeit (um 2004) nicht richtig funktionierte. Der Fehler wurde nie behoben, da /dev/urandom recht gut funktioniert. Daher müssen Sie es vortäuschen, indem Sie die Einstellung verschleiern, indem Sie /dev/./urandom verwenden, 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 die Java-Versionen 5 und folgende, das sich aus Problemen mit /dev/urandom auf Linux-Systemen im Jahr 2004 ergab.

  • In diesem Artikel ist wahrscheinlich ein Tippfehler, da Java Bug 6202721 tatsächlich besagt: “Dies ist ein Problem, wenn /dev/urandom ausgewählt wurde, weil /dev/random nicht richtig funktioniert.”. Daher ist Ihre Schlussfolgerung “aufgrund von Problemen mit /dev/urandom” falsch. In der akzeptierten Antwort finden Sie eine Erklärung zur Auswahl von /dev/urandom anstelle des Standardwerts (/dev/random). Es ist in den meisten Fällen eine gute Idee.

    – Kamal

    30. April 2020 um 11:33 Uhr

Dies ist nicht mehr erforderlich, wenn Sie JDK 8 oder höher verwenden

Das Problem wurde von Java behoben und hier sind einige Links

Umriss

SHA1PRNG und NativePRNG wurden korrigiert, um die Eigenschaften der SecureRandom-Seed-Quelle in der Datei java.security korrekt zu respektieren. (Der obskure Workaround mit file:///dev/urandom und file:/dev/./urandom ist nicht mehr erforderlich.)

Für weitere Informationen (suchen Sie auf der Seite nach zufällig):

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​​​​​​​

  • Ich glaube nicht, dass das richtig ist. Zum Hintergrund: tersesystems.com/blog/2015/12/17/… Die Fixes in Java 8 sagen nur, dass sie jetzt die Eigenschaften der SecureRandom-Seed-Quelle in der Datei java.security respektieren. Aber standardmäßig enthält das immer noch: securerandom.source=file:/dev/random Die “obskure Problemumgehung” bezieht sich auf das zusätzliche ./ im Dateinamen, das auch in der akzeptierten (und am häufigsten gewählten) Antwort hier erwähnt wird.

    – Kamal

    27. April 2020 um 19:13 Uhr


  • Der “obskure Workaround” war nur unter bestimmten Umständen erforderlich, siehe: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721

    – Kamal

    27. April 2020 um 19:24 Uhr

  • Genau das ist der Punkt, der wurde in Java 8 behoben. Laut Fehlerbericht war der “obskure Workaround” (Hinzufügen des zusätzlichen ./ im Dateinamen) nach Java 1.4.2 und bis 6 erforderlich. Ich gehe davon aus auch in Java 7, sonst würde es in Java 8 nicht als behoben erwähnt werden. Das Setzen von /dev/urandom anstelle von /dev/random ist jedoch immer noch erforderlich, wenn Sie ein nicht blockierendes Gerät verwenden möchten.

    – Kamal

    30. April 2020 um 11:08 Uhr

  • @souser es wurde auch in openjdk 8 behoben

    – Veranstaltungsort

    9. Juli 2020 um 7:19 Uhr


  • Das ist nicht richtig, heute habe ich dieses Problem, dann habe ich es benutzt, dann wurde es behoben, also glaube ich nicht, dass es auf Java 8 behoben ist

    – Mugeesh Husain

    24. September 2020 um 6:20 Uhr

1098510cookie-checkWofür ist die Option java.security.egd?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy