java security random

java - ¿Es seguro SecureRandom.ints()?



security (3)

Sí, SecureRandom

proporciona un generador de números aleatorios (RNG) criptográficamente fuerte.

Un factor importante para un RNG seguro es la semilla.

Por lo tanto, cualquier material semilla pasado a un objeto SecureRandom debe ser impredecible, y todas las secuencias de salida de SecureRandom deben ser criptográficamente fuertes, como se describe en RFC 4086: Requisitos de aleatoriedad para la seguridad.

Adelante y úsalo. Si está interesado en los detalles, lea el JavaDoc que describe los diversos enfoques utilizados por las implementaciones.

Se sabe que la clase SecureRandom proporciona una seguridad criptográfica sólida para el número aleatorio generado. java.util.Random es inseguro para la situación que requiere seguridad criptográfica. El uso típico de SecureRandom es:

SecureRandom random = new SecureRandom(); byte bytes[] = new byte[20]; random.nextBytes(bytes);

Sin embargo, conocí un caso:

SecureRandom random = new SecureRandom(); int number = random.ints();

El método ints() se hereda de la clase java.util.Random . Estoy confundido cuando SecureRandom que es un generador de números aleatorios seguro, utiliza un método heredado del generador de números aleatorios inseguros, ¿es seguro?


Si, es seguro.

El examen de código de java.util.Random muestra que ints() crea un spliterator que usa internalNextInt(...) para generar los enteros aleatorios. Eso a su vez llama a nextInt() en this . En el caso de java.security.SecureRandom , nextInt() se nextInt() para generar un número aleatorio "seguro" 1 .

Puede confirmar esto usted mismo mirando el código fuente.

1 - Por supuesto, en realidad no tiene sentido llamar "entero" a un entero o una secuencia de enteros. Y hay situaciones en las que SecureRandom puede no tener las propiedades que necesita. (Depende de la implementación real de RNG o PRNG utilizada por la clase, la calidad de la fuente de entropía proporcionada por la semilla o el sistema suministrado, etc.) Pero SecureRandom :: ints () generará una secuencia de enteros que tiene las mismas propiedades como si hicieras una secuencia de llamadas SecureRandom :: nextInt () en el mismo objeto. Si la última secuencia es adecuada para sus propósitos (cualesquiera que sean), entonces también lo es la primera.


Random.ints() es un método que devuelve un IntStream . Un IntStream no es seguro ni inseguro: es un flujo de números.

La "seguridad" de la secuencia de entradas devueltas por el método depende de la implementación del método. SecureRandom genera sus valores "aleatorios" de manera más segura que Random . Comparten la misma API y, por lo tanto, puede usarla en un contexto determinado según sus requisitos.

Por lo tanto, el hecho de que herede de una clase insegura es irrelevante para la seguridad: puede confiar razonablemente en que la clase SecureRandom es tan segura como lo dice la documentación.

Considere una analogía con HashSet : esto no garantiza el orden del iterador ; sin embargo, LinkedHashSet , una subclase de HashSet garantiza el pedido de iteradores. La garantía de LinkedHashSet es coherente con la garantía de HashSet , porque un pedido específico es uno de los posibles pedidos que podrían observarse con "pedido no garantizado" (después de todo, debe devolver los elementos en algún orden).

Del mismo modo, Random no garantiza la seguridad de la secuencia de entradas devueltas; SecureRandom hace garantías más fuertes. Pero no hay ninguna razón por la cual la secuencia de SecureRandom un SecureRandom no pueda ser devuelta por un Random , por coincidencia.