Secondo la documentazione , i diversi algoritmi utilizzati da SecureRandom sono, in ordine di preferenza:
- Sulla maggior parte dei sistemi * NIX
- NativePRNG
- SHA1PRNG
- NativePRNGBlocking
- NativePRNGNonBlocking
- Su sistemi Windows
- SHA1PRNG
- Windows PRNG
Da quando hai chiesto di Linux, sto ignorando l'implementazione di Windows, e anche SunPKCS11 che è davvero disponibile solo su Solaris, a meno che tu non l'abbia installato tu stesso - e quindi non te lo chiederesti.
Secondo la stessa documentazione, sono utilizzati questi algoritmi
SHA1PRNG
Il seeding iniziale viene attualmente eseguito tramite una combinazione di attributi di sistema e il dispositivo di raccolta entropia java.security.
NativePRNG
nextBytes()
utilizza gli /dev/urandom
generateSeed()
usi/dev/random
NativePRNGBlocking
nextBytes()
e generateSeed()
use/dev/random
NativePRNGNonBlocking
nextBytes()
e generateSeed()
utilizzo/dev/urandom
Ciò significa che se lo usi SecureRandom random = new SecureRandom()
, scende in tale elenco fino a quando non ne trova uno che funziona, che in genere sarà NativePRNG. Ciò significa che si semina da /dev/random
(o lo utilizza se si genera esplicitamente un seme), quindi lo utilizza /dev/urandom
per ottenere i byte, gli ints, il double, i booleani successivi, il what-have-yous.
Poiché /dev/random
sta bloccando (blocca fino a quando non ha abbastanza entropia nel pool di entropia), ciò può impedire le prestazioni.
Una soluzione a ciò sta usando qualcosa di simile all'haged per generare abbastanza entropia, un'altra /dev/urandom
invece sta usando . Mentre potresti impostarlo per l'intero jvm, una soluzione migliore è farlo per questa specifica istanza di SecureRandom
, usando SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking")
. Si noti che quel metodo può generare NoSuchAlgorithmException se NativePRNGNonBlocking, quindi prepararsi al fallback al valore predefinito.
SecureRandom random;
try {
random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
random = new SecureRandom();
}
Si noti inoltre che su altri sistemi * nix, /dev/urandom
potrebbe comportarsi diversamente .
È /dev/urandom
abbastanza casuale?
La saggezza convenzionale vuole che /dev/random
sia abbastanza casuale. Tuttavia, alcune voci differiscono. In "Il modo giusto di utilizzare SecureRandom" e "Miti su / dev / urandom" , si sostiene che /dev/urandom/
sia altrettanto buono.
Gli utenti dello stack Sicurezza delle informazioni concordano con questo . Fondamentalmente, se devi chiedere, /dev/urandom
va bene per il tuo scopo.