Saltearse al contenido

Aleatoriedad débil (RNG)

Muchísima seguridad depende de números aleatorios impredecibles: claves, IV/nonces, tokens de sesión, resets de contraseña, OTPs, identificadores. Cuando el generador es débil o predecible, el atacante predice esos valores y rompe el sistema sin tocar la criptografía en sí.

PRNG estándar (rand(), Math.random(), mt_rand, java.util.Random)
rápido pero PREDECIBLE: dado suficiente salida, se recupera el estado y se predice el resto
NUNCA para nada de seguridad
CSPRNG (criptográficamente seguro)
/dev/urandom, getrandom(), secrets (Python), crypto.randomBytes (Node),
SecureRandom (Java), RNGCryptoServiceProvider/.NET
diseñado para que la salida sea impredecible aun conociendo salidas previas
Semilla predecible seed = time() o PID -> espacio de semillas pequeño -> fuerza bruta
PRNG no cripto para tokens tokens de sesión/reset generados con rand()/Mersenne Twister
-> se recupera el estado y se predicen tokens futuros/pasados
Entropía insuficiente al arranque dispositivos IoT/VMs generan claves con poca entropía
-> CLAVES REPETIDAS o factorizables entre dispositivos
Nonce/IV predecible o fijo rompe CTR/GCM/CBC (ver crypto-sym)
k repetido en (EC)DSA reutilizar el nonce 'k' al firmar REVELA la clave privada

Predicción de Mersenne Twister (laboratorio)

Sección titulada «Predicción de Mersenne Twister (laboratorio)»
# MT19937 (usado por mt_rand de PHP, random de Python, Math.random de muchos runtimes):
# con 624 salidas consecutivas de 32 bits se reconstruye el estado interno y se predice todo
# herramienta: randcrack (Python)
from randcrack import RandCrack
rc = RandCrack()
for v in observadas_624: rc.submit(v)
rc.predict_randint(0, n) # siguiente valor "aleatorio"
# aplicación real: tokens/IDs predecibles -> secuestro de cuentas, bypass de OTP
# si dos firmas usan el MISMO k: con las dos firmas (r,s1),(r,s2) y los mensajes
# se despeja k y luego la CLAVE PRIVADA. Caso histórico: PS3 (Sony) firmaba con k fijo.
# detección: mismo valor r en dos firmas distintas = k repetido
# estudios masivos de claves RSA públicas en Internet hallaron claves que comparten un primo
# (GCD entre módulos != 1) por RNG débil en el arranque de routers/IoT -> factorización trivial
  • randcrack (MT19937), PRNG crackers específicos por lenguaje, sage/z3 para modelar.
  • openssl/msieve/yafu para la parte de factorización; análisis de tokens con Burp Sequencer (calidad de aleatoriedad de sesión).
  • Usar siempre un CSPRNG del sistema para claves, IV/nonces, tokens, resets y OTPs (secrets, crypto.randomBytes, SecureRandom).
  • Nonce/k único por operación (o firma determinista RFC 6979 en ECDSA); IV aleatorio.
  • Asegurar entropía suficiente al arranque (hardware RNG, no generar claves en el primer boot sin entropía).
  • Tokens largos (≥128 bits) y opacos; auditar con Burp Sequencer.
  • Debian OpenSSL (CVE-2008-0166): un parche redujo la entropía → claves SSH/SSL predecibles a escala mundial.
  • PS3 / fail0verflow (2010): ECDSA con k fijo reveló la clave de firma de Sony.
  • Mining your Ps and Qs (2012): claves RSA/DSA factorizables por primos compartidos (RNG débil en IoT).
  • Numerosos bugs de tokens de reset predecibles por usar PRNG no criptográfico.
  • Identificar qué usa aleatoriedad (tokens, resets, OTP, IV/nonce, claves)
  • ¿PRNG no criptográfico (rand/mt_rand/Math.random)?
  • Recoger salidas y probar predicción (randcrack para MT19937)
  • Tokens/IDs: ¿secuenciales o predecibles? (Burp Sequencer)
  • Firmas ECDSA/DSA: ¿valor r repetido? → k reutilizado
  • Claves RSA: ¿comparten primos (GCD)? (baja entropía)
  • Verificar uso de CSPRNG y RFC 6979 en la defensa