A che cosa serve l'opzione java.security.egd?


23

In un progetto a cui sto lavorando, l'applicazione viene lanciata usando un comando simile al seguente:

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

Non ho mai visto l' java.security.egdopzione prima. Cercando un po ', sembra usato per configurare la generazione di numeri casuali in un'applicazione Java.

È giusto? Quando dovrebbe essere applicato?

Risposte:


30

Le applicazioni Java possono e devono utilizzare la classe java.security.SecureRandom per produrre valori casuali crittograficamente forti utilizzando un generatore di numeri pseudo-casuali crittograficamente forte ( CSPRNG ). Le implementazioni JDK standard della classe java.util.Random non sono considerate crittograficamente forti.

I sistemi operativi simili a Unix dispongono di /dev/randomun file speciale che serve numeri pseudo casuali che accedono al rumore ambientale raccolto dai driver di dispositivo e da altre fonti. Tuttavia, si blocca se è disponibile meno entropia di quanto richiesto ; /dev/urandomin genere non si blocca mai, anche se il seme del generatore di numeri pseudocasuali non è stato completamente inizializzato con entropia dall'inizio. Esiste ancora un terzo file speciale, /dev/arandomche si blocca dopo l'avvio fino a quando il seme non è stato inizializzato in modo sicuro con abbastanza entropia e quindi non si blocca mai più.

Per impostazione predefinita, JVM esegue il seeding della classe SecureRandom utilizzando /dev/random, pertanto il codice Java può bloccarsi in modo imprevisto . L'opzione -Djava.security.egd=file:/dev/./urandomnell'invocazione della riga di comando utilizzata per avviare il processo Java indica /dev/urandominvece a JVM di utilizzare .

Il supplemento /./sembra fare in modo che la JVM utilizzi l' algoritmo SHA1PRNG che utilizza SHA-1 come base del PRNG (Pseudo Random Number Generator). È più forte dell'algoritmo NativePRNG utilizzato quando /dev/urandomè specificato.

Infine, esiste un mito che /dev/urandomè un generatore di numeri pseudo casuali, un PRNG, mentre /dev/randomè un generatore di numeri casuali "vero" . Questo semplicemente non è vero, entrambi /dev/randome /dev/urandomsono alimentati dallo stesso CSPRNG (generatore di numeri pseudocasuali crittograficamente sicuro). Solo il comportamento quando il rispettivo pool esaurisce l'entropia, secondo alcune stime, differisce: /dev/randomblocchi, mentre /dev/urandomnon lo è.

Che dire dell'entropia che sta per finire? Non importa

Si scopre che "apparire casuali" è il requisito di base per molti dei nostri blocchi crittografici. E se prendi l'output di un hash crittografico, deve essere indistinguibile da una stringa casuale in modo che le cifre lo accettino. Questo è il motivo dell'utilizzo dell'algoritmo SHA1PRNG, in quanto utilizza una funzione hash e un contatore, insieme a un seme.

Quando dovrebbe essere applicato?

Direi sempre.

Fonti:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


MODIFICA 04/2020:

Un commento menziona una modifica al comportamento della classe SecureRandom in Java 8.

SHA1PRNG e NativePRNG sono stati corretti per rispettare correttamente le proprietà dell'origine seme SecureRandom nel file java.security. (L'oscura soluzione alternativa utilizzando file: /// dev / urandom e file: / dev /./ urandom non è più necessaria.)

Ciò era già stato sottolineato dai test citati nella sezione Fonti sopra. Il supplemento /./è necessario per modificare l'algoritmo utilizzato da SecureRanom in Java 8 da NativePRNG a SHA1PRNG.

Tuttavia, ho alcune notizie che vorrei condividere. Secondo JEP-273 , da Java 9 la classe SecureRandom implementa i tre meccanismi deterministici di generazione casuale di bit (DRBG) descritti nel NIST 800-90Ar1 . Questi meccanismi implementano algoritmi moderni forti come SHA-512 e AES-256.

Il JDK aveva due tipi di implementazioni SecureRandom :

  • Uno è dipendente dalla piattaforma e basato su chiamate native o dispositivi OS come la lettura /dev/{u}randomsu Unix o l'utilizzo di CryptoAPI su Windows. Le ultime versioni di Linux e Windows supportano già DRBG, ma le versioni precedenti e i sistemi integrati potrebbero non esserlo .
  • L'altro tipo è un'implementazione Java pura che utilizza un'implementazione RNG basata su SHA1 precedente, che non è così forte come gli algoritmi utilizzati dai meccanismi approvati DRBG.

Nel frattempo, la Guida per gli sviluppatori di Java 13 Security continua a leggere

Su Linux e macOS, se il dispositivo di raccolta entropia in java.security è impostato su file:/dev/urandomo file:/dev/random, NativePRNG è preferito a SHA1PRNG. Altrimenti, è preferito SHA1PRNG.

Per chiarire come i nuovi meccanismi DRBG giocano insieme ai PRNG precedenti, eseguo alcuni test su macOS (Darwin) con AdoptOpenJDK (build 13.0.2 + 8). Ecco i risultati:

file: / dev / random
Ordine di preferenza per i provider:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev / urandom
Ordine di preferenza per i provider:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev /./ urandom
Ordine di preferenza per i provider:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

Conclusione:

Consiglio di utilizzare -Djava.security.egd=file:/dev/./urandomper assicurarsi di sfruttare l' implementazione SecureRandom più potente disponibile indipendentemente dalla piattaforma utilizzata, evitando al contempo di bloccare il codice in modo imprevisto.


1
A partire da Java 8, la "soluzione oscura" dell'ulteriore ./ nel nome del file non è più richiesta, quindi puoi semplicemente usare "/ dev / urandom", vedi: docs.oracle.com/javase/8/docs / technotes / guide / security /…
Kamal

Grazie per l'aggiornamento della risposta (specialmente sulle modifiche in Java 9 e 13). Per quanto ne so, a partire da Java 8 che imposta il "dispositivo di raccolta entropia" su / dev / urandom o /dev/./urandom dovrebbe produrre esattamente gli stessi risultati, altrimenti la correzione non avrebbe senso. Dal punto di vista del sistema operativo, quelli puntano allo stesso file identico, quindi ciò non dovrebbe influire su Java (lo ha fatto prima della correzione, ma era un bug, non una funzionalità prevista). Pertanto, la tua dichiarazione "Il extra /./ è necessario per influenzare la selezione PRNG." non dovrebbe più essere vero, a partire da Java 8.
Kamal

Grazie @Kamal per i tuoi commenti. La mia frase precedente "Selezione PRNG" non era abbastanza chiara. L'ho riformulato per chiarire che sto parlando dell'algoritmo utilizzato: NativePRNG o SHA1PRNG. L'uso di /dev/urandomseleziona NativePRNG alimentato da /dev/urandommentre /dev/./urandompreleva SHA1PRNG (anche alimentato da /dev/urandom) quando si utilizza Java 8. Da Java 9 in poi, DRBG ha la precedenza quando /dev/./urandomviene specificata l'origine.
dbaltor

1

Questo non è più necessario se si utilizza JDK 8 o versione successiva

Il problema è stato risolto da Java e qui ci sono alcuni collegamenti

Contorno

SHA1PRNG e NativePRNG sono stati corretti per rispettare correttamente le proprietà dell'origine seme SecureRandom nel file java.security. (L'oscura soluzione alternativa utilizzando file: /// dev / urandom e file: / dev /./ urandom non è più necessaria.)

Per maggiori informazioni (cerca random nella pagina):

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


Non credo sia corretto. Per lo sfondo: tersesystems.com/blog/2015/12/17/… Le correzioni in Java 8 dicono solo che ora rispettano le proprietà dell'origine seed SecureRandom nel file java.security. Ma per impostazione predefinita contiene ancora: securerandom.source = file: / dev / random La "soluzione oscura" si riferisce al nome extra / nel nome del file, menzionato anche dalla risposta accettata (e più votata) qui.
Kamal,

La "soluzione oscura" era richiesta solo in circostanze specifiche, vedere: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal

@Kamal I link che hai pubblicato si riferiscono a Java 6 e precedenti,
Venu Madhav,

Questo è esattamente il punto, è stato risolto in Java 8. Secondo il bug report, "Java oscura" (aggiungendo l'ulteriore ./ nel nome del file) era richiesto dopo Java 1.4.2 e fino a 6. Suppongo anche in Java 7, altrimenti non verrebbe menzionato come riparato in Java 8. Tuttavia, è necessario impostare / dev / urandom invece di / dev / random, se si desidera utilizzare un dispositivo non bloccante.
Kamal,

0

Questo è legato alla differenza di Linux /dev/randome /dev/urandomgeneratore di numeri casuali.

Tratto da questo link

Il bug Java 6202721 afferma che java.security.SecureRandom utilizza / dev / random anziché / dev / urandom anche se viene specificato / dev / urandom perché al momento (intorno al 2004) / dev / urandom non funzionava correttamente. Il bug non è mai stato invertito ora che / dev / urandom funziona abbastanza bene. Pertanto, è necessario falsificarlo oscurando l'impostazione utilizzando /dev/./urandom per forzare l'uso di SHA1PRNG anziché / dev / random.

Per rispondere alla tua domanda

Quando dovrebbe essere applicato?

Basato sul link sopra, è qualcosa di unico per Java versioni 5 e seguenti che derivava da problemi con / dev / urandom su sistemi Linux nel 2004.


Probabilmente c'è un errore di battitura in quell'articolo, dato che il Bug 6202721 di Java in realtà afferma "Questo è un problema se è stato scelto / dev / urandom perché / dev / random non funziona correttamente". Pertanto la tua conclusione "derivante da problemi con / dev / urandom" non è corretta. Vedi la risposta accettata per una spiegazione sulla scelta di / dev / urandom invece del valore predefinito (/ dev / random). È una buona idea nella maggior parte dei casi.
Kamal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.