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.