Domanda Seme sicuro sicuro in Java


Questo pezzo di codice è sicuro?

 SecureRandom randomizer = new SecureRandom(String.valueOf(new Date().getTime()).getBytes());

È questo il modo giusto per istanziare il seme di un caso casuale?


10
2017-09-03 13:53


origine


risposte:


No, dovresti evitare il SecureRandom(byte[]) costruttore. È sia pericoloso che non portatile.

Non è portabile perché si comporta in modo diverso su Windows rispetto ad altri sistemi operativi.

Sulla maggior parte dei sistemi operativi, l'algoritmo predefinito è "NativePRNG", che ottiene dati casuali dal sistema operativo (in genere "/dev/random") e ignora il seme che fornisci.

Su Windows, l'algoritmo predefinito è "SHA1PRNG", che combina il tuo seme con un contatore e calcola un hash del risultato.

Questa è una brutta notizia nel tuo esempio, perché l'input (l'attuale ora UTC in millisecondi) ha un intervallo relativamente piccolo di valori possibili. Ad esempio, se un utente malintenzionato sa che il RNG è stato seminato nelle ultime 48 ore, può restringere il seme a meno di 228 valori possibili, cioè hai solo 27 bit di entropia.

Se d'altra parte hai usato il valore predefinito SecureRandom() costruttore su Windows, avrebbe chiamato il nativo CryptoGenRandom funzione per ottenere un seed a 128 bit. Quindi, specificando il tuo seme hai indebolito la sicurezza.

Se vuoi davvero sostituire il seme predefinito (ad es. Per il test dell'unità) devi anche specificare l'algoritmo. Per esempio.

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("abcdefghijklmnop".getBytes("us-ascii"));

Guarda anche Come risolvere il problema delle prestazioni con Java SecureRandom?
e questo post del blog: http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/


24
2017-09-03 16:35



Penso che sia meglio lasciare il seme di SecureRandom stesso. Questo viene fatto chiamando nextBytes immediatamente dopo la sua creazione (chiamare setSeed lo impedirà).

final byte[] dummy = new byte[512];
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.nextBytes(dummy);

Si desidera utilizzare SHA1PRNG perché garantisce un'implementazione rapida non bloccante anche su Linux, dove l'impostazione predefinita non lo è.


2
2017-09-04 12:10



Il codice è ragionevolmente sicuro perché non usa solo il seme dato per seminare il randomizzatore.

Non è molto più casuale del semplice utilizzo.

SecureRandom randomizer = new SecureRandom();

1
2017-09-03 13:56