Generar números aleatorios fuertes en Java

RECU-0607 (Recurso Ejemplo)

Introducción

Los generadores de números pseudoaleatorios (PRNGs) se basan en el uso de algoritmos matemáticos deterministas para producir una secuencia de números con buenas propiedades estadísticas, pero los números presentados no son genuinamente al azar.

PRNG suele comenzar con un valor de inicialización aritmética. El algoritmo usa esta semilla para generar un valor de salida y una nueva semilla, que se utiliza para generar el valor siguiente, y así sucesivamente.

Descripción

La API de Java proporciona un PRNG, la clase java.util.Random. Este PRNG es portátil y repetible por lo que, si dos instancias de azar se crean utilizando la misma semilla, se pueden generan secuencias idénticas de números en todas las implementaciones de Java.

A veces la misma semilla se reutiliza en la inicialización de la aplicación o después de cada reinicio del sistema. En otras ocasiones, la hora actual obtenida del reloj del sistema es utilizada para obtener la semilla. Un adversario puede aprender el valor de la semilla mediante la realización de algunos reconocimientos sobre el blanco vulnerable y proceder a construir una tabla de consulta para la estimación de valores futuros de la semilla.

Ejemplos

Un ejemplo de código vulnerable es el siguiente: si se utiliza la misma semilla se obtiene la misma secuencia de números como resultado, las cifras no son "al azar". Este ejemplo de código utiliza la clase insegura java.util.Random.

import java.util.Random;
// ...
Random number = new Random(123L);
//...
for (int i = 0; i < 20; i++) {
  // Generate another random integer in the range [0, 20]
  int n = number.nextInt(21);
  System.out.println(n);
}

Es recomendable utilizar la clase java.security.SecureRandom que produce números aleatorios de calidad, como en el ejemplo siguiente:

import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
// ...
public static void main (String args[]) {
   try {
     SecureRandom number = SecureRandom.getInstance("SHA1PRNG");
     // Generate 20 integers 0..20
     for (int i = 0; i < 20; i++) {
       System.out.println(number.nextInt(21));
     }
   } catch (NoSuchAlgorithmException nsae) { 
     // Forward to handler
   }
}



Contenidos relacionados

Pautas
Área: Desarrollo » Seguridad » Cifrado
Código Título Tipo Carácter
PAUT-0202 Generación de tokens seguros Pauta Directriz Obligatoria