¿Es seguro el hilo SecureRandom?

103

¿Es SecureRandomseguro el hilo? Es decir, después de inicializarlo, ¿se puede confiar en que el acceso al siguiente número aleatorio es seguro para subprocesos? Examinar el código fuente parece mostrar que lo es, y este informe de error parece indicar que su falta de documentación como seguro para subprocesos es un problema de javadoc. ¿Alguien ha confirmado que de hecho es seguro para subprocesos?

Yishai
fuente

Respuestas:

108

Sí lo es. Se extiende Random, que siempre tuvo una implementación segura para subprocesos de facto , y, desde Java 7, garantiza explícitamente la seguridad para subprocesos.

Si muchos subprocesos utilizan uno solo SecureRandom, puede haber una contención que perjudique el rendimiento. Por otro lado, la inicialización de una SecureRandominstancia puede ser relativamente lenta. Si es mejor compartir un RNG global o crear uno nuevo para cada hilo, dependerá de su aplicación. La ThreadLocalRandomclase podría usarse como patrón para proporcionar una solución que admita SecureRandom.

erickson
fuente
3
Gracias por la actualización. Curiosamente, el error está marcado como cerrado como "no se solucionará". Pero lo arreglaron de todos modos. Bueno, no les envidio el tamaño de su base de datos de errores.
Yishai
4
la inicialización de a SecureRandomno solo puede ser lenta, sino que potencialmente puede bloquearse debido a la falta de entropía
Walter Tross
8
Tenga en cuenta que ThreadLocalRandom es muy fácil de descifrar, por lo que si planea exponer el valor generado al mundo, use SecureRandom en su
walv
2
Voy a arriesgarme aquí y decir que esta respuesta es incorrecta. El contrato para Random, que garantiza la seguridad de los subprocesos, no es vinculante para las subclases. Ciertamente, todas las demás propiedades de Random documentadas no son vinculantes para las subclases, por lo que no veo por qué se debe asumir la seguridad de subprocesos.
Presidente James K. Polk
2
@JamesKPolk No preservar una propiedad del supertipo violaría el principio de sustituibilidad.
erickson
11

La implementación actual de SecureRandomes segura para subprocesos, específicamente los dos métodos mutantes nextBytes(bytes[])ysetSeed(byte[]) están sincronizados.

Bueno, por lo que he podido decir, todos los métodos de mutación eventualmente se enrutan a través de esos dos métodos y SecureRandomanula algunos métodos Randompara garantizar eso. Lo cual funciona, pero podría resultar frágil si se cambia la implementación en el futuro.

La mejor solución es sincronizar manualmente en la SecureRandominstancia primero. Esto significa que cada pila de llamadas adquirirá dos bloqueos en el mismo objeto, pero eso suele ser muy económico 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);
    }
Matt Quail
fuente
3
Al menos en JDK 10, SecureRandom se basa en un proveedor y verifica si el proveedor es seguro para subprocesos, y solo sincroniza si no lo es, en nextBytes.
nafg
java.security.SecureRandom#nextBytesen Java 8 no está sincronizado. ¿Podría especificar en qué versión de Java encontró sincronizado #nextBytes?.
Jaime Hablutzel