Il thread SecureRandom è sicuro?


103

È SecureRandomthread-safe? Cioè, dopo averlo inizializzato, è possibile fare affidamento sull'accesso al numero casuale successivo per essere thread-safe? L'esame del codice sorgente sembra mostrare che lo è, e questa segnalazione di bug sembra indicare che la sua mancanza di documentazione come thread safe è un problema di javadoc. Qualcuno ha confermato che è effettivamente thread-safe?

Risposte:


108

Sì. Si estende Random, che ha sempre avuto un'implementazione sicura per i thread di fatto , e, da Java 7, garantisce esplicitamente la sicurezza dei thread.

Se molti thread ne utilizzano uno SecureRandom, potrebbero esserci contese che danneggiano le prestazioni. D'altra parte, l'inizializzazione di SecureRandomun'istanza può essere relativamente lenta. Se è meglio condividere un RNG globale o crearne uno nuovo per ogni thread dipenderà dall'applicazione. La ThreadLocalRandomclasse potrebbe essere utilizzata come modello per fornire una soluzione che supporti SecureRandom.


3
Grazie per l'aggiornamento. Stranamente, il bug è contrassegnato come chiuso come "non risolverà". Ma l'hanno risolto comunque. Oh beh, non li invidio la dimensione del loro database di bug.
Yishai

4
l'inizializzazione di a SecureRandomnon solo può essere lenta, ma può potenzialmente bloccarsi a causa della mancanza di entropia
Walter Tross

8
Tieni presente che ThreadLocalRandom è molto facile da decifrare, quindi se prevedi di esporre il valore generato al mondo, usa SecureRandom invece jazzy.id.au/default/2010/09/20/…
walv

2
Ho intenzione di uscire su un arto qui e dire che questa risposta non è corretta. Il contratto per Random, che garantisce la sicurezza dei thread, non è vincolante per le sottoclassi. Certamente tutte le altre proprietà di Random documentate non sono vincolanti per le sottoclassi, quindi non vedo perché si dovrebbe presumere la thread-safety.
Presidente James K. Polk

2
@JamesKPolk La mancata conservazione di una proprietà del supertipo violerebbe il principio di sostituibilità.
erickson

11

L'attuale implementazione di SecureRandomè thread-safe, in particolare i due metodi mutanti nextBytes(bytes[])esetSeed(byte[]) sono sincronizzati.

Bene, per quanto ne so, tutti i metodi di mutazione vengono alla fine instradati attraverso questi due metodi e SecureRandomsovrascrive alcuni metodi Randomper assicurarlo. Che funziona ma potrebbe essere fragile se l'implementazione viene modificata in futuro.

La soluzione migliore è sincronizzare manualmente SecureRandomprima sull'istanza. Ciò significa che ogni stack di chiamate acquisirà due lock sullo stesso oggetto, ma di solito è molto economico sulle JVM moderne. Cioè, non c'è molto danno nella sincronizzazione esplicita di te stesso. Per esempio:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }

3
Almeno in JDK 10, SecureRandom è basato su un provider e controlla se il provider è thread-safe, sincronizzando solo se non lo è, in nextBytes.
nafg

java.security.SecureRandom#nextBytesin Java 8 non è sincronizzato. Potresti specificare in quale versione di Java hai trovato sincronizzato #nextBytes?
Jaime Hablutzel
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.