Niveau :      
Résumé : /dev/random /dev/urandom

Quelle différence y a-t-il entre /dev/random et /dev/urandom ? Et d'abord à quoi servent-il ?

Aléatoire

Qu'est-ce qu'un nombre aléatoire ? C'est un nombre faisant partie d'une série dont on ne peut pas prédire le prochain à partir des nombres précédents de la série.

Il existe de nombreuses méthodes pour créer des nombres aléatoires. Je vous donne la plus mauvaise : rand : i -> 0

Mais il existe aussi des suites moins prévisibles, par exemple prendre le dernier chiffre d'une opération récursive produisant de grands nombres. Voire complètement imprévisible comme utiliser la mesure d'un bruit blanc.

Il existe donc plusieurs niveaux d'"aléatoirité" ou de "prévisibilité". Un bon générateur qui peut par exemple être utilisé en cryptographie est en pratique soit un générateur matériel, soit un générateur basé sur un état interne et une fonction de hachage forte.

Les générateurs logiciels sont appelés PRNG (pseudo random number generator). Puisqu'un tel algorithme est déterministe, il faut l'initialiser avec des valeurs vraiment aléatoires pour éviter qu'on puis en deviner la sortie en devinant comment il a été initialisé.

Entropie

Sous linux il y a deux sources de nombres aléatoires, /dev/random et /dev/urandom.

La première utilise uniquement l'entropie disponible pour fournir des nombres aléatoires et le second est un générateur pseudo aléatoire initialisé avec cette entropie.

Mais qu'est-ce que l'entropie ?

On y vient, l'entropie est une quantité de bits qu'on considère comme totalement aléatoires, donc générés par des évènements physiques. Sous linux, lorsqu'on ne dispose pas d'une puce générant ces nombres aléatoires, on utilise des choses comme l'intervalle entre deux interruptions pour créer les bits d'entropie.

Mais alors quel générateur faut-il utiliser ?

/dev/urandom est pseudo aléatoire, très pratique pour la plupart des usages, il permet de générer autant de nombres qu'on veut à un rythme soutenu.

/dev/random est complètement aléatoire, on ne l'utilise que lorsqu'on en a vraiment besoin, il utilise directement le pool d'entropie et ne donc fournir qu'un nombre limité de bits, il se remplit progressivement mais lentement.

Il me manque de l'entropie

Si vous avez besoin de beaucoup de nombres vraiment aléatoires (pour générer de nombreuses clés ssh par exemple), vous allez avoir besoin de beaucoup d'entropie.

Avant de tenter de rajouter de l'entropie, mesurons-la.

Deux méthode pour ca :

# pour obtenir l'entropie disponible à un instant t
$ cat /proc/sys/kernel/random/entropy_avail

# pour voir la vitesse de remplissage du pool d'entropie (en le vidant)
$ cat /dev/random | cpipe -ngr -vt > /dev/null

C'est là qu'on découvre cpipe, petit outil très sympa pour mesurer la bande passante d'un pipe.

Maintenant on peut laisser cette commande tourner en tache de fond et tenter d'ajouter de l'entropie pour trouver la meilleurs méthode. Quelques tests (en root de préférence)

$ while true; do cat /boot/vmlinux.gz > /dev/random; done
# -> rien
$ find / > /dev/null
# -> pas mal
$ # déplacer la souris
# -> un peu moins
$ yes # dans un terminal ssh distant
# -> un peu moins
$ ssh  machine distante "cat /dev/zero" > /dev/null
# -> rien

Attention, les résultats ne sont pas forcément les mêmes sur une vm. Conclusion temporaire : les sources d'entropie sont le disque dur (résultat du find) et la souris.

A vous d'en trouver d'autres ...

Bon j'en ai une autre pour vous. En fait il existe une api à base d'ioctl pour ajouter de l'entropie au noyau depuis l'espace utilisateur. Mais il faut faire attention à bien jouter de la vraie entropie et pas une suite de nombres prévisibles.

Pour faire ça, quelqu'un a fait un démon permettant de remplir ces bits avec différentes sources : la carte son, une entrée vidéo ou les variations de précision du timer idée originale, n'est-il pas ?