2009-09-22 27 views
82

¿SecureRandom es seguro? Es decir, después de inicializarlo, ¿se puede confiar en que el acceso al siguiente número aleatorio sea seguro para la ejecución de subprocesos? Al examinar el código fuente parece mostrar que sí, y this bug report parece indicar que su falta de documentación como hilo seguro es un problema de Javadoc. ¿Alguien ha confirmado que, de hecho, es seguro para subprocesos?¿SecureRandom es seguro para subprocesos?

Respuesta

83

Sí, lo es. Se extiende Random, que siempre se tenía de hecho una aplicación multi-hilo, y, a partir Java 7, explicitly guarantees threadsafety.

Si muchos hilos están utilizando un solo SecureRandom, puede haber contención que perjudica el rendimiento. Por otro lado, la inicialización de una instancia SecureRandom puede ser relativamente lenta. Si es mejor compartir un RNG global, o crear uno nuevo para cada hilo dependerá de su aplicación. La clase ThreadLocalRandom se puede usar como un patrón para proporcionar una solución que admita SecureRandom.

+3

Gracias por la actualización. Curiosamente, el error está marcado como "no se arregla". Pero lo arreglaron de todos modos. Oh, bueno, no les envidio el tamaño de su base de datos de errores. – Yishai

+2

inicializar un 'SecureRandom' no solo puede ser lento, sino que también puede bloquearse debido a la falta de entropía –

+1

@WalterTross ¿Se bloquea? He visto que los sistemas tardan 10 o 15 minutos, pero nunca he visto uno colgado. Una implementación que no está garantizada para continuar alimentando su grupo de entropía, aunque lentamente, parece un error en el sistema operativo. – erickson

1

Sí. Es totalmente seguro para subprocesos. En realidad, me quejaría de que el candado es demasiado agresivo. Todo el engineNextBytes() está sincronizado.

Para ser franco con usted, no sabría si no es seguro. La cuestión de roscado, probablemente, se introduce una mayor aleatoriedad :)

+9

Es * Seguro * Aleatorio, es muy importante usarlo con precisión. No creo que introduzca más aleatoriedad. P.ej. Al azar seguro no hilo podría producir el mismo número aleatorio en varios hilos - podría significar que un hilo podría robar un número generado por otro hilo, podría ser explotado por un pirata informático. – kan

8

La implementación actual de SecureRandom es seguro para subprocesos, específicamente los dos métodos de mutación nextBytes(bytes[]) y setSeed(byte[]) están sincronizados.

Bueno, por lo que he podido decir, todos los métodos de mutación finalmente se enrutan a través de esos dos métodos, y SecureRandom anula algunos métodos en Random para garantizar que. Lo cual funciona, pero podría ser frágil si la implementación cambia en el futuro.

La mejor solución es sincronizar manualmente en la instancia SecureRandom primero. Esto significa que cada pila de llamadas adquirirá dos bloqueos en el mismo objeto, pero eso suele ser muy barato en las JVM modernas. Es decir, no hay mucho daño en sincronizarse explícitamente. Por ejemplo:

SecureRandom rnd = ...; 

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