¿El generador pseudoaleatorio no se inicializa desde el (grupo de entropía)?

5

Los manuales de RHEL5 establecen que / dev / urandom usará el grupo de entropía hasta que se agote, y luego recurrirá a un algoritmo de pseudo-aleatoriedad de retroceso, para que nunca se bloquee.

Pero al investigar el sistema, he encontrado que el generador pseudoaleatorio (/dev/urandom) se inicializa por /var/lib/random-seed como se indica en el script de inicio /etc/rc.sysinit .

Pero el /var/lib/random-seed obtiene sus datos de /dev/urandom o.O !! como se indica en el guión del archivo /etc/init.d/halt al ingresar el nivel de ejecución 0 (apagado) o el nivel de ejecución 6 (reinicio).

¿Entonces /dev/urandom nunca usa el grupo de entropía ?!

Estoy confundido ... cualquier ayuda sería apreciada por favor :)

    
pregunta Michael Bloomberg 29.04.2012 - 07:46
fuente

3 respuestas

6

/ dev / urandom siempre intentará devolver el valor más aleatorio que pueda. En el peor de los casos, utilizará la criptografía para "estirar" los últimos bits de entropía en el grupo para completar su solicitud. En contraste, / dev / random bloqueará hasta que el grupo de entropía esté lo suficientemente lleno como para llenar los bytes solicitados, por lo que / dev / random garantizará un valor más aleatorio . Sin embargo, / dev / random bloqueará hasta que el almacén de entropía sea lo suficientemente grande como para llenar los bytes solicitados, lo cual es inaceptable en casi todos los usos. Si el grupo de entropía está lleno, entonces / dev / urandom y / dev / random son idénticos .

Cuando rc.sysinit se apaga , copia 512 bytes de /dev/urandom . En este punto es probable que la máquina haya estado encendida durante un tiempo, por lo que el grupo de entropía ha tenido la oportunidad de llenarse. Allí para este archivo es más probable que sea una parte pura del grupo de entropía. Sin embargo, si el grupo de entropía no está lleno, es mejor tener algo que nada (o lo que es peor, bloquear hasta que el grupo de entropía esté lo suficientemente lleno antes de apagarse).

En un sistema Linux es muy importante que el grupo de entropía se llene durante el arranque. Para satisfacer esta necesidad, la acción de cierre es guardar el grupo de entropía en el disco, y la puesta en marcha es volver a cargar este grupo de entropía muy temprano en el proceso de arranque. En un sistema Linux, las ubicaciones de memoria ASLR y los valores de secuencia TCP se calculan con este conjunto de entropía. Si se vació la agrupación, entonces, en cada inicio, el diseño del espacio de memoria de los procesos del daemon no sería muy aleatorio y, para un proceso como el de su demonio SMTP, podría explotarse más fácilmente a través de un desbordamiento de búfer. Esto también afecta su susceptibilidad a los ataques MITM. Esto se debe a que sería más fácil para un atacante predecir los valores de secuencia TCP necesarios para completar el protocolo de enlace de tres vías de TCP.

Si alguna vez ve una distribución de Linux que no se restaura no es un grupo de entropía en el arranque, entonces es una vulnerabilidad que debe informarse .

Si desea más información, intente leer los comentarios del código en random.c

    
respondido por el rook 29.04.2012 - 08:58
fuente
5

Permítame complementar las otras respuestas explicando, con cierto nivel de detalle, cómo funciona un PRNG con un grupo de entropía. Esto es un poco de una simplificación excesiva, ya que la implementación actual de Linux usa múltiples pools. Pero debería ayudar a darle una idea básica de cómo funciona el esquema.

Primero, contiene tres partes clave:

  1. Un grupo de entropía. Esto es básicamente una matriz de bytes. Un objetivo clave del sistema es garantizar que un atacante no conozca estos bytes.

  2. A PRNG. Este es un componente algorítmico que opera en el grupo de entropía para producir resultados aleatorios.

  3. Una colección de sondas de entropía. Estas aleatorias 'mías' provienen de actividades como la red y el disco y las agregan al grupo de entropía.

El PRNG "saca" el grupo de entropía. El algoritmo exacto es complicado, pero la idea básica es que realiza una operación de hash criptográficamente segura en el grupo, genera parte del hash y mezcla parte del hash de nuevo en el grupo. (En el código de Linux actual, en realidad utiliza dos operaciones SHA1).

Las sondas "llenan" el grupo de entropía. El algoritmo exacto es aún más complicado (GFSR torcido), pero la idea básica es que la agrupación se mezcle y que la información de las sondas sea XOR en la agrupación.

Además, el sistema mantiene una medida de cuánta entropía hay en el grupo. Se supone que la producción aleatoria "agota" el grupo y que la adición de entropía "llena" el grupo. Hay un sentido teórico en el que esto es cierto, pero efectivamente no importa.

Por ejemplo, supongamos un conjunto de 2.048 bytes y un atacante que no sabe nada sobre el contenido del conjunto. Y luego supongamos que ve 8 bytes de salida de la agrupación. En teoría, eso descarta todas las condiciones iniciales posibles excepto 1 en 2 ^ 64 y deja solo aquellas que producirían esos 8 bytes exactos. Pero no hay una forma conocida, ni siquiera concebible, en que un atacante podría usar esa información.

Sin agregación de entropía adicional y con 1GB de salida del PRNG, un atacante tiene toda la información que necesita para determinar la condición inicial del grupo y predecir el próximo resultado del grupo. El problema es que no hay otro método conocido para hacerlo que no sea intentar todas las posibles condiciones iniciales de 2 ^ (8 * 2048).

A efectos prácticos, solo hay dos ataques posibles:

  1. Adivina los contenidos añadidos de la agrupación. Esto falla si hay más de, digamos, 128 bits de datos desconocidos mezclados en el conjunto Un atacante no puede probar 2 ^ 128 o más combinaciones.

  2. Adivina el contenido del grupo en algún momento posterior. Pero esto requiere adivinar todo .

En resumen, a menos que haya un defecto en el algoritmo, la salida de la agrupación no revela información útil sobre el contenido de la agrupación. Mientras un atacante no pueda predecir o adivinar todos la información mezclada en el grupo hasta el punto en que se extrajo del grupo, no puede predecir lo que saldrá del grupo. (¡Suponiendo que no pueda mirar dentro de la piscina, por supuesto!)

    
respondido por el David Schwartz 30.04.2012 - 13:07
fuente
3

Descripción general. No te culpo por estar confundido. Hay mucha información errónea por ahí que (injustamente) arroja aspersiones en /dev/urandom .

De hecho, /dev/urandom está seguro. La versión corta es: usa /dev/urandom e ignora las cosas que puedas escuchar sobre él. /dev/urandom es la opción correcta para casi todas las situaciones en las que necesita números aleatorios de alta calidad criptográfica. /dev/random casi nunca es la elección correcta.

Detalles técnicos. Para conocer la justificación de mis reclamos, consulte las siguientes preguntas:

Hay mucho escrito allí, y no lo voy a repetir.

El archivo de inicialización aleatoria. Para una aproximación de primer orden, puede ignorar el archivo de inicialización aleatoria. Ese es un mecanismo estándar que está presente en la distribución de Linux para garantizar que /dev/urandom sea seguro. Como desarrollador de aplicaciones, no tienes que preocuparte por eso. Sucede bajo el capó. Todo lo que necesita saber es que está presente por diseño, y está ahí por una buena razón, y es beneficioso.

¿Quieres la explicación completa? OK, aqui esta. Para que sea seguro, /dev/urandom necesita obtener al menos 128 bits de bits aleatorios verdaderos de algún lugar. Una vez que tiene 128 bits o más de verdadera entropía, a partir de ese momento puede contar con que su salida sea segura, criptográficamente sólida e impredecible, sin importar cuánta salida extraiga de ella. Entonces la única pregunta es, ¿de dónde vienen esos fragmentos de verdadera aleatoriedad?

El kernel de Linux tiene muchas fuentes de las cuales recopila una verdadera aleatoriedad: por ejemplo, el tiempo de las interrupciones (por ejemplo, pulsaciones de teclas, E / S) y otras cosas similares de bajo nivel. El kernel acumula gradualmente esta aleatoriedad en una agrupación que utiliza /dev/urandom , y una vez que estas fuentes hayan producido un agregado de aproximadamente 128 bits o más de verdadera aleatoriedad, está bien. Sin embargo, estas fuentes producen entropía a una tasa relativamente baja. Por lo tanto, inmediatamente después de arrancar, es probable que aún no hayan producido suficiente entropía. Para solucionar esto, la distribución de Linux tiene un mecanismo para retener la entropía que se ha reunido en los reinicios. cuando apaga la computadora, la computadora obtiene algo de aleatoriedad de la agrupación de entropía de /dev/urandom (recuerde, la agrupación de entropía probablemente ya tenga entropía adecuada por lo que esta debería ser una aleatoriedad fuerte y buena) y la guarda en el archivo de inicialización aleatoria . La próxima vez que inicie la computadora, en el momento del arranque, el sistema operativo recibe la entropía del archivo de inicialización aleatoria, lo que garantiza que la agrupación de /dev/urandom ahora tenga al menos 128 bits de buena aleatoriedad. Por lo tanto, una vez que su computadora acumule suficiente entropía en el grupo, la salida de /dev/urandom será buena a partir de ese momento, sin importar cuántas veces reinicie la computadora.

    
respondido por el D.W. 30.04.2012 - 04:54
fuente

Lea otras preguntas en las etiquetas