Entropía: su uso en los generadores aleatorios

Publicado por Diego Córdoba en

Hoy les voy a comentar algunos conceptos sobre aleatoriedad de la información y entropía en un generador random en sistemas Linux, particularmente de la entropía, su concepto y usos.


Entropía

La entropía, también llamada Entropía de Shannon, mide la incertidumbre de una fuente de información, es una medida del desorden. Podemos considerar a la cantidad de información promedio que contienen los símbolos utilizados en un texto.

Por ejemplo, los símbolos «la», «es» «a» o «que» son muy comunes en el lenguaje coloquial, mientras que «libro», «monitor» y «mesa» no lo son, por lo que si omitimos alguno de los primeros en un texto, su significado seguramente no cambiará, mientras que si omitimos algunos de los segundos, el resultado de la interpretación se verá drásticamente alterado.

entropia_1 entropia

Ahora bien, si logramos que todos los símbolos tengan la misma probabilidad de ocurrencia, su distribución de probabilidad sería uniforme, y estaríamos alcanzando la máxima entropía posible.

Esto es muy útil en la generación de datos aleatorios en un sistema operativo, y además resulta de suma importancia si esos datos se utilizan luego para generar claves de cifrado simétrico o asimétrico.

Los dispositivos de generación aleatoria en *nix

En sistemas Linux disponemos de dos dispositivos de generación de valores aleatorios, /dev/random y /dev/urandom.

Estos dispositivos son archivos especiales, o nodos, que pueden ser utilizados como archivos de lectura comunes, y los datos obtenidos vendrán determinados por múltiples fuentes de entropía del sistema operativo.

binary-1282366_960_720 entropia

/dev/random bloqueará la generación aleatoria hasta que el pool de entropía esté lleno, es decir, quedará en espera de generar datos aleatorios hasta que sean generados nuevos valores desde las fuentes de entropía disponibles. Esto puede ocasionar que la generación de valores aleatorios sea muy lenta, pero a su vez, se garantizará mayor «aleatoriedad» y desorden.

/dev/urandom por su parte no se bloqueará, y en vez de esperar a que el pool de entropía se llene, reutilizará los valores obtenidos para generar nuevos. La generación aleatoria suele ser más rápida que la de /dev/random, aunque los datos generados pueden tener algún tipo de correlación.

Usos Comunes

/dev/urandom suele utilizarse para cuando necesitamos grandes cantidades de números aleatorios para pruebas, o para formatos de bajo nivel con dd, puesto que la generación será rápida.

/dev/random es sumamente útil y recomendado para la generación aleatoria utilizada en funciones criptográficas, generación de claves, etc.

Un generador de passwords de linea de comandos

Veamos la siguiente función de bash que nos permitiría generar passwords desde línea de comandos de una manera sencilla:

genpasswd() {
        tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${1:-8} | xargs
}

Podemos pasarle un argumento numérico que será la cantidad de caracteres de la password, en caso contrario, será, por ejemplo, de 8 caracteres.

El comando tr se utiliza en este caso para truncar la salida a un set de caracteres determinado, en este caso, las letras del abecedario mayúsculas, minúsculas, los números del 0 al 9, y el guion bajo.

Los valores serán generados desde /dev/urandom y serán filtrados por tr. A dicha salida luego le truncaremos a una determinada cantidad de caracteres, 10 por defecto, o el valor que pasemos por argumento.

Veamos algunos ejemplos de su ejecución:

diego@sol:~$ genpasswd
xKZrUCeX
diego@sol:~$ genpasswd
EXvm4873
diego@sol:~$ genpasswd 20
IBUx7KAKiRX_IKPB_9M1
diego@sol:~$ genpasswd 5
TGqhT

Mejorando la seguridad

¿No acabamos de decir que /dev/urandom maneja menos entropía, y por consiguiente /dev/random sería más apto para generación de claves y contraseñas?

Esto es cierto, pero ocurre que los generadores de entropía en el sistema, como los movimientos de memoria, I/O en disco, o gestión de gráfica, no son muchas veces suficientes, y la generación random utilizando /dev/random en la función anterior sería extremadamente lenta (hacer la prueba :P).

Analicemos ahora nuestro valor de entropía en el sistema:

diego@sol:~$ cat /proc/sys/kernel/random/entropy_avail
86

A muchos de ustedes les ocurrirá igual, valores de entropía muy bajos… 100 sería el mínimo recomendable! Esta es la razón por la que nuestro generador random es sumamente lento.

Esto es fácilmente solucionable utilizando una nueva fuente de entropía por software: rng-tools.

El daemon rngd actúa como un puente entre el generador aleatorio por hardware TRNG (true random number generator) y el generador pseudo-random del kernel Linux PRNG (pseudo-random number generator) utilizado por /dev/random, de modo que podemos, mediante este daemon, aumentar el ancho de banda de /dev/random, haciendo que la generación aleatoria sea mucho más veloz!

Más entropía con rng-tools

Procedemos a instalarlo, por suerte se encuentra en los repositorios:

sudo apt-get install rng-tools

El nombre del paquete suele ser el mismo en otras distros, como ArchLinux:

sudo pacman -S rng-tools

Y ahora lo configuramos para que genere mayor entropía en el sistema en base a una nueva fuente… utilizaremos para tal caso, el dispositivo /dev/urandom. Editamos el archivo /etc/default/rng-tools y descomentamos y modificamos la siguiente línea:

HRNGDEVICE=/dev/urandom

Esto permitirá que la entropía en el sistema ahora sea enriquecida por /dev/urandom, de modo que el pool de entropía será completado mucho más rápido que con las fuentes convencionales, y /dev/random permitirá una generación más rápida.

Corramos el generador de entropía:

diego@sol:~$ sudo service rng-tools start
Starting Hardware RNG entropy gatherer daemon: rngd.

Y analicemos ahora nuestro valor de entropía disponible:

diego@sol:~$ cat /proc/sys/kernel/random/entropy_avail
2027

Actualizando nuestra función generadora

Por consiguiente, podremos cambiar en este momento nuestra función para que tome como entrada de valores aleatorios al dispositivo /dev/random de esta forma:

genpasswd() {
        tr -dc A-Za-z0-9_ < /dev/random | head -c ${1:-8} | xargs
}

Y probemos ahora la generación:

diego@sol:~$ genpasswd
LkUWxvVl
diego@sol:~$ genpasswd 5
5Y9yT
diego@sol:~$ genpasswd 50
ZzoLhYPwCvK3e8hivezZ2oEgc2TPaDGNstzpkJd4EHuIVOgJUm

Las claves generadas serán ahora más seguras… sí, hagamos el favor de creerle ahora a nuestra función de generación de valores aleatorios 🙂

Cabe concluir que no es necesaria tanta paranoia, en general, para la generación de contraseñas de usuario, pero sí sería recomendable para la generación de claves mayores, como claves privadas y públicas asimétricas RSA por ejemplo.

haveged, otra alternativa:

Otro software interesante para poder generar entropía en el sistema, similar al rng-tools, es haveged, y podemos instalarlo y ejecutarlo de la siguiente forma (Debian):

sudo apt-get install haveged
sudo systemctl start haveged

Para Arch, por ejemplo:

sudo pacman -S haveged
sudo systemctl enable haveged

Haveged proviene de la contracción de las palabras HArdware Volatile Entropy Gathering and Expansion, un daemon similar al RNG

Otra forma, manual y no tan elegante a mi gusto, es utilizar el comando dd para generar movimiento de datos, por ejemplo:

sudo dd if=/dev/zero of=/tmp/zeros.tmp bs=500M count=5

Conclusiones

Hemos aprendido los conceptos fundamentales de entropía aplicada a los generadores pseudoaleatorios de un sistema operativo, y hemos conocido dos herramientas, rng-tools y haveged, para Linux, que nos permiten aumentar la entropía o el desorden en nuestro sistema.

Debe tenerse en cuenta que las nuevas versiones de Linux incorporan cambios en cuestión de gestión de entropía y generadores aleatorios… pasen por este artículo para actualizarse ->

¡Espero que les resulte de utilidad esta entrada!


Entropía: un video Explicativo

En nuestro canal de youtube hemos colgado un video donde explicamos estos conceptos de una forma más amena, esperamos te resulte interesante!



¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador