Ist SecureRandom-Thread sicher?

103

Ist der SecureRandomFaden sicher? Kann man sich nach der Initialisierung darauf verlassen, dass der Zugriff auf die nächste Zufallszahl threadsicher ist? Die Untersuchung des Quellcodes scheint zu zeigen, dass dies der Fall ist, und dieser Fehlerbericht scheint darauf hinzudeuten, dass die fehlende Dokumentation als threadsicher ein Javadoc-Problem ist. Hat jemand bestätigt, dass es tatsächlich threadsicher ist?

Yishai
quelle

Antworten:

108

Ja, so ist es. Es wird erweitert Random, das immer eine de facto threadsichere Implementierung hatte, und garantiert ab Java 7 explizit die Threadsicherheit.

Wenn viele Threads einen einzelnen verwenden SecureRandom, kann es zu Konflikten kommen, die die Leistung beeinträchtigen. Andererseits kann das Initialisieren einer SecureRandomInstanz relativ langsam sein. Ob es am besten ist, ein globales RNG freizugeben oder für jeden Thread ein neues zu erstellen, hängt von Ihrer Anwendung ab. Die ThreadLocalRandomKlasse kann als Muster verwendet werden, um eine unterstützende Lösung bereitzustellen SecureRandom.

erickson
quelle
3
Danke für das Update. Seltsamerweise ist der Fehler als geschlossen markiert und wird nicht behoben. Aber sie haben es trotzdem behoben. Na ja, ich beneide sie nicht um die Größe ihrer Fehlerdatenbank.
Yishai
4
Das Initialisieren von a SecureRandomkann nicht nur langsam sein, sondern möglicherweise aufgrund fehlender Entropie hängen bleiben
Walter Tross
8
Beachten Sie bitte, dass ThreadLocalRandom sehr leicht zu knacken ist. Wenn Sie also vorhaben, den generierten Wert der Welt zugänglich zu machen
walv
2
Ich werde hier auf die Beine gehen und sagen, dass diese Antwort falsch ist. Der Vertrag für Random, der die Thread-Sicherheit garantiert, ist für Unterklassen nicht bindend. Sicherlich sind alle anderen dokumentierten Eigenschaften von Random für Unterklassen nicht bindend, daher verstehe ich nicht, warum Thread-Sicherheit angenommen werden sollte.
Präsident James K. Polk
2
@JamesKPolk Wenn eine Eigenschaft des Supertyps nicht beibehalten wird, wird das Substituierbarkeitsprinzip verletzt.
Erickson
11

Die aktuelle Implementierung von SecureRandomist threadsicher, insbesondere die beiden Mutationsmethoden, nextBytes(bytes[])und setSeed(byte[])wird synchronisiert.

Soweit ich das beurteilen konnte, werden alle Mutationsmethoden schließlich durch diese beiden Methoden geleitet und SecureRandomüberschreiben einige Methoden, Randomum dies sicherzustellen. Was funktioniert, aber spröde werden könnte, wenn die Implementierung in Zukunft geändert wird.

Die beste Lösung besteht darin, SecureRandomzuerst die Instanz manuell zu synchronisieren . Dies bedeutet, dass jeder Aufrufstapel zwei Sperren für dasselbe Objekt erhält, was bei modernen JVMs normalerweise sehr billig ist. Das heißt, es schadet nicht, sich explizit zu synchronisieren. Beispielsweise:

    SecureRandom rnd = ...;

    byte[] b = new byte[NRANDOM_BYTES];
    synchronized (rnd) {
        rnd.nextBytes(b);
    }
Matt Wachtel
quelle
3
Zumindest in JDK 10 basiert SecureRandom auf einem Anbieter und prüft in nextBytes, ob der Anbieter threadsicher ist, und synchronisiert nur, wenn dies nicht der Fall ist.
Nafg
java.security.SecureRandom#nextBytesin Java 8 ist nicht synchronisiert. Könnten Sie bitte angeben, in welcher Java-Version Sie eine synchronisierte gefunden haben #nextBytes?
Jaime Hablutzel