Do czego służy opcja java.security.egd?

22

W projekcie, nad którym pracuję, aplikacja jest uruchamiana za pomocą polecenia podobnego do tego:

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

Nigdy wcześniej nie widziałem takiej java.security.egdopcji. Trochę szukając, wydaje się być używany do konfiguracji generowania liczb losowych w aplikacji Java.

Czy to jest poprawne? Kiedy należy zastosować?

Davioooh
źródło

Odpowiedzi:

29

Aplikacje Java mogą i powinny używać klasy java.security.SecureRandom do tworzenia kryptograficznie silnych losowych wartości za pomocą silnie kryptograficznie generatora liczb pseudolosowych ( CSPRNG ). Standardowe implementacje JDK klasy java.util.Random nie są uważane za kryptograficznie silne.

Uniksowe systemy operacyjne mają /dev/randomspecjalny plik, który obsługuje pseudolosowe liczby uzyskujące dostęp do szumu otoczenia zebranego ze sterowników urządzeń i innych źródeł. Jednak blokuje się, jeśli dostępna jest mniejsza entropia niż wymagana ; /dev/urandomzazwyczaj nigdy nie blokuje, nawet jeśli ziarno generatora liczb pseudolosowych nie zostało w pełni zainicjowane entropią od momentu rozruchu. Nadal istnieje trzeci plik specjalny, /dev/arandomktóry blokuje się po uruchomieniu, dopóki ziarno nie zostanie bezpiecznie zainicjowane z wystarczającą ilością entropii, a następnie nigdy więcej nie blokuje.

Domyślnie JVM wykorzystuje klasę SecureRandom/dev/random , dlatego kod Java może zostać nieoczekiwanie zablokowany . Opcja -Djava.security.egd=file:/dev/./urandomw wywołaniu wiersza poleceń używana do uruchomienia procesu Java mówi JVM, aby /dev/urandomzamiast tego użyła .

Dodatkowa /./wydaje się zmusić JVM do korzystania z algorytmu SHA1PRNG, który wykorzystuje SHA-1 jako podstawę PRNG (Pseudo Random Number Generator). Jest silniejszy niż algorytm NativePRNG używany, gdy /dev/urandomjest określony.

Wreszcie istnieje mit, który /dev/urandomjest pseudolosowym generatorem liczb losowych, PRNG, podczas gdy /dev/randomjest „prawdziwym” generatorem liczb losowych . To po prostu nie jest prawdą, zarówno /dev/randomi /dev/urandomsą karmione przez samego CSPRNG (kryptograficznie bezpieczny generator liczb pseudolosowych). Tylko zachowanie, gdy w ich puli zabraknie entropii, według niektórych szacunków, różni się: /dev/randomblokuje, podczas gdy /dev/urandomnie.

Co powiesz na niski poziom entropii? To nie ma znaczenia

Okazuje się, że „wyglądanie losowo” jest podstawowym wymogiem dla wielu naszych kryptograficznych elementów składowych. A jeśli weźmiesz wynik szyfrowania kryptograficznego, musi on być nie do odróżnienia od losowego ciągu, aby szyfry go zaakceptowały. To jest powód zastosowania algorytmu SHA1PRNG, ponieważ wykorzystuje on funkcję skrótu i ​​licznik wraz z ziarnem.

Kiedy należy zastosować?

Zawsze tak mówię.

Źródła:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


EDYCJA 04/2020:

Komentarz wspomina o zmianie zachowania klasy SecureRandom w Javie 8.

Naprawiono SHA1PRNG i NativePRNG, aby odpowiednio przestrzegać właściwości źródła inicjującego SecureRandom w pliku java.security. (Niejasne obejście przy użyciu file: /// dev / urandom i file: / dev /./ urandom nie jest już wymagane).

Zostało to już wskazane w testach wymienionych w sekcji Źródła powyżej. Dodatkowa /./jest wymagana do zmiany algorytmu używanego przez SecureRanom w Javie 8 z NativePRNG na SHA1PRNG.

Mam jednak kilka wiadomości, którymi chciałbym się podzielić. Zgodnie z JEP-273 , od Java 9 klasa SecureRandom implementuje trzy mechanizmy deterministycznego generatora bitów losowych (DRBG) opisane w NIST 800-90Ar1 . Mechanizmy te implementują nowoczesne algorytmy tak silne, jak SHA-512 i AES-256.

JDK miał dwa rodzaje implementacji SecureRandom :

  • Jeden jest zależny od platformy i oparty na natywnych połączeniach lub urządzeniach z systemem operacyjnym, takich jak czytanie /dev/{u}randomw systemie Unix lub używanie CryptoAPI w systemie Windows. Najnowsze wersje systemów Linux i Windows obsługują już DRBG, ale starsze wersje i systemy wbudowane mogą nie .
  • Drugi rodzaj to czysta implementacja Java, która wykorzystuje starszą implementację RNG opartą na SHA1, która nie jest tak silna jak algorytmy stosowane przez zatwierdzone mechanizmy DRBG.

Tymczasem Java 13 Security Developer's Guide wciąż czyta

W systemach Linux i macOS, jeśli urządzenie do gromadzenia entropii w java.security jest ustawione na file:/dev/urandomlub file:/dev/random, wówczas NativePRNG jest lepszy niż SHA1PRNG. W przeciwnym razie preferowany jest SHA1PRNG.

Aby wyjaśnić, w jaki sposób nowe mechanizmy DRBG działają razem z poprzednimi PRNG, uruchamiam kilka testów na macOS (Darwin) z AdoptOpenJDK (kompilacja 13.0.2 + 8). Oto wyniki:

plik: / dev / random
Kolejność preferencji dla dostawców:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

plik: / dev / urandom
Kolejność preferencji dla dostawców:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

plik: / dev /./ urandom
Kolejność preferencji dla dostawców:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

Wniosek:

Polecam użyć, -Djava.security.egd=file:/dev/./urandomaby upewnić się, że wykorzystasz najsilniejszą dostępną implementację SecureRandom, niezależnie od używanej platformy, unikając nieoczekiwanego zablokowania kodu.

dbaltor
źródło
1
Począwszy od wersji Java 8 „niejasne obejście” dodatkowego pliku ./ w nazwie pliku nie jest już wymagane, więc można po prostu użyć polecenia „/ dev / urandom”, patrz: docs.oracle.com/javase/8/docs / technotes / guide / security /…
Kamal
Dziękujemy za aktualizację odpowiedzi (szczególnie na temat zmian w Javie 9 i 13). Według mojego zrozumienia, od Java 8 ustawienie „urządzenia gromadzącego entropię” na / dev / urandom lub /dev/./urandom powinno dawać dokładnie takie same wyniki, w przeciwnym razie poprawka nie miałaby sensu. Z perspektywy systemu operacyjnego wskazują one na ten sam identyczny plik, co nie powinno wpływać na Javę (miało to miejsce przed poprawką, ale był to błąd, a nie zamierzona funkcja). Dlatego stwierdzenie „Dodatkowe /./ jest wymagane, aby wpłynąć na wybór PRNG”. nie powinno już być prawdą, począwszy od Java 8.
Kamal
Dzięki @Kamal za komentarze. Moje poprzednie zdanie „Wybór PRNG” nie było wystarczająco jasne. Przeredagowałem go, aby wyjaśnić, że mówię o zastosowanym algorytmie: NativePRNG lub SHA1PRNG. Użycie opcji /dev/urandomNativePRNG zasilanych przez /dev/urandompodczas /dev/./urandompobierania SHA1PRNG w górę (również zasilanych przez /dev/urandom) podczas korzystania z Java 8. Począwszy od Java 9, DRBG ma pierwszeństwo, gdy /dev/./urandompodano źródło.
dbaltor
1

Nie jest to już wymagane, jeśli używasz JDK 8 lub nowszej wersji

Problem został rozwiązany przez Javę i oto kilka linków

Zarys

Naprawiono SHA1PRNG i NativePRNG, aby odpowiednio przestrzegać właściwości źródła inicjującego SecureRandom w pliku java.security. (Niejasne obejście przy użyciu file: /// dev / urandom i file: / dev /./ urandom nie jest już wymagane).

Aby uzyskać więcej informacji (wyszukaj losowo na stronie):

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
źródło
Nie wierzę, że to jest poprawne. W tle: tersesystems.com/blog/2015/12/17/ ... Poprawki w Javie 8 mówią tylko, że teraz szanują właściwości źródła inicjującego SecureRandom w pliku java.security. Ale domyślnie nadal zawiera: securerandom.source = plik: / dev / random „Nieokreślone obejście” odnosi się do dodatkowego ./ w nazwie pliku, wspomnianego również tutaj przez zaakceptowaną (i najczęściej głosowaną) odpowiedź.
Kamal
„Niejasne obejście” było wymagane tylko w określonych okolicznościach, patrz: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal
@Kamal Opublikowane linki odnoszą się do Java 6 i wcześniejszych,
Venu Madhav,
Dokładnie o to chodzi, został naprawiony w Javie 8. Według raportu o błędzie „niejasne obejście” (dodanie dodatkowego ./ w nazwie pliku) było wymagane po Javie 1.4.2 i do wersji 6. Zakładam, że także w Javie 7, w przeciwnym razie nie byłoby wspomniane jako poprawione w Javie 8. Ustawienie / dev / urandom zamiast / dev / random jest jednak nadal wymagane, jeśli chcesz używać urządzenia nieblokującego.
Kamal
0

Jest to związane z różnicą generatora linuksa /dev/randomi /dev/urandomgeneratora liczb losowych.

Zaczerpnięte z tego linku

Błąd Java 6202721 stwierdza, że ​​java.security.SecureRandom używa / dev / random zamiast / dev / urandom, nawet jeśli podano / dev / urandom, ponieważ w tym czasie (około 2004) / dev / urandom nie działał poprawnie. Błąd nigdy nie został odwrócony teraz, gdy / dev / urandom działa całkiem dobrze. Dlatego musisz go wyłudzić, zasłaniając ustawienie za pomocą /dev/./urandom, aby wymusić użycie SHA1PRNG zamiast / dev / random.

Odpowiedzieć na Twoje pytanie

Kiedy należy zastosować?

Na podstawie powyższego łącza jest to coś unikalnego dla wersji Java 5 i następnych, które wynikało z problemów z / dev / urandom w systemach Linux w 2004 roku.

Ruelos Joel
źródło
W tym artykule jest prawdopodobnie literówka, ponieważ Java Bug 6202721 faktycznie stwierdza: „Jest to problem, jeśli wybrano / dev / urandom, ponieważ / dev / random nie działa poprawnie”. Dlatego twój wniosek „wynikający z problemów z / dev / urandom” jest niepoprawny. Zobacz zaakceptowaną odpowiedź, aby uzyskać wyjaśnienie dotyczące wyboru / dev / urandom zamiast domyślnego (/ dev / random). W większości przypadków jest to dobry pomysł.
Kamal