62 votes

Quelle est la graine la plus sûre pour la génération de nombres aléatoires ?

Quelles sont les sources d'entropie les plus sûres pour ensemencer un générateur de nombres aléatoires ? Cette question est indépendante du langage et de la plate-forme et s'applique à toute machine sur un réseau. Idéalement, je cherche des sources disponibles pour une machine dans un environnement en nuage ou un serveur fourni par une société d'hébergement.

Il y a deux faiblesses importantes à garder à l'esprit. L'utilisation du temps pour l'envoi d'un générateur de nombre aléatoire est une violation de CWE-337 . L'utilisation d'un petit espace pour les semences constituerait une violation du CWE-339 .

84voto

Thomas Pornin Points 36984

Voici quelques réflexions. Si vous êtes impatient, passez directement à la conclusion, à la fin.

1. Qu'est-ce qu'une graine sécurisée ?

La sécurité n'est définie que par rapport à un modèle d'attaque. Nous voulons ici une séquence de n bits, qui a n d'entropie par rapport à l'attaquant : en d'autres termes, que n'importe lequel des possibles 2 n pour cette séquence sont également probables du point de vue de l'attaquant.

Il s'agit d'un modèle qui se rapporte à la information à la disposition de l'attaquant. L'application qui génère et utilise la graine (normalement dans un PRNG) connaît la graine exacte ; le fait que la graine soit "sûre" n'est pas une propriété absolue de la graine ou même du processus de génération de la graine. Ce qui importe, c'est la quantité d'informations dont dispose l'attaquant sur le processus de génération. Ce niveau d'information varie largement en fonction de la situation ; par exemple, sur un système multi-utilisateurs (disons de type Unix, avec une séparation des applications renforcée par le matériel), la synchronisation précise des accès à la mémoire peut révéler des informations sur la façon dont un processus nominalement protégé lit la mémoire. Même un attaquant distant peut obtenir de telles informations ; ceci a été a démontré (dans des conditions de laboratoire) sur le cryptage AES (les implémentations AES typiques utilisent des tables internes, avec des schémas d'accès qui dépendent de la clé ; l'attaquant force les manques de cache et les détecte grâce à un timing précis des réponses du serveur).

La durée de vie de la graine doit être prise en compte. La graine est sûre tant qu'elle reste inconnue de l'attaquant ; cette propriété doit rester vraie par la suite. En particulier, il ne doit pas être possible de récupérer la graine à partir d'extraits de la sortie ultérieure du PRNG. Idéalement, même l'obtention de l'état complet du PRNG à un moment donné ne devrait donner aucun indice sur les bits que le PRNG a produits auparavant.

Ce que je veux dire ici, c'est qu'une graine n'est "sûre" que si elle est utilisée dans un contexte où elle peut rester sûre, ce qui implique plus ou moins un PRNG cryptographiquement sûr et un stockage inviolable. Si un tel stockage est disponible, la graine la plus sûre est celle qui a été générée. une fois il y a longtemps, et utilisé dans un PRNG sécurisé hébergé par du matériel inviolable.

Malheureusement, un tel matériel est coûteux (il s'appelle un HSM et coûte quelques centaines ou milliers de dollars), et ce coût s'avère généralement difficile à justifier (une mauvaise graine n'empêchera pas un système de fonctionner ; c'est le problème habituel de la non-testabilité de la sécurité). C'est pourquoi il est d'usage d'opter pour des solutions "essentiellement logicielles". Puisque les logiciels ne sont pas aptes à fournir un stockage confidentiel à long terme, la durée de vie de la graine est arbitrairement réduite : une nouvelle graine est obtenue périodiquement. Dans Fortuna Ce réensemencement est censé se produire au moins une fois par mégaoctet de données pseudo-aléatoires générées.

En résumé, dans une configuration sans HSM, une graine sûre est une graine qui peut être obtenue relativement facilement (puisque nous le ferons assez souvent) en utilisant des données qui ne peuvent pas être recueillies par l'attaquant.

2. Mélange

Les sources de données aléatoires ne produisent pas de beaux bits uniformes (chaque bit ayant la valeur 1 avec une probabilité exacte de 1). 0.5 et les valeurs des bits sont indépendantes les unes des autres). Au lieu de cela, les sources aléatoires produisent des valeurs dans un ensemble spécifique à la source. Ces valeurs peuvent être codées sous forme de séquences de bits, mais on n'en a pas pour son argent : pour avoir n bits d'entropie, vous devez avoir des valeurs qui, lorsqu'elles sont encodées, utilisent beaucoup plus que les bits d'entropie. n bits.

L'outil cryptographique à utiliser ici est un PRF qui accepte une entrée d'une longueur arbitraire et produit un fichier n -bit de sortie. Une PRF cryptographiquement sécurisée de ce type est modélisée comme une oracle aléatoire En bref, il n'est pas possible, d'un point de vue informatique, de prédire quoi que ce soit sur la sortie de l'oracle pour une entrée donnée sans l'essayer.

En ce moment, nous avons fonctions de hachage . Les fonctions de hachage doivent remplir quelques propriétés de sécurité, à savoir la résistance aux préimages, aux secondes préimages et aux collisions. Nous analysons généralement les fonctions de hachage en essayant de voir comment elles s'écartent du modèle de l'oracle aléatoire. Il y a un point important ici : une PRF qui suit le modèle de l'oracle aléatoire sera une bonne fonction de hachage, mais il peut y avoir de bonnes fonctions de hachage (dans le sens de la résistance aux préimages et aux collisions) qui sont néanmoins faciles à distinguer d'un oracle aléatoire. En particulier, le SHA-2 (SHA-256, SHA-512...) sont considérées comme sûres, mais s'écartent du modèle de l'oracle aléatoire en raison de l'"attaque par extension de longueur" (étant donné h(m) il est possible de calculer h(m || m') pour un message partiellement contraint m' sans savoir m ). L'attaque par extension de longueur ne semble pas fournir de raccourci pour la création de pré-images ou de collisions, mais elle montre que ces fonctions de hachage ne sont pas des oracles aléatoires. Pour le Concours SHA-3 Le NIST a déclaré que les candidats ne devaient pas autoriser une telle "extension de la longueur".

L'étape du mélange n'est donc pas facile. Votre meilleure chance est encore, pour l'instant, d'utiliser SHA-256 ou SHA-512, et de passer à SHA-3 lorsqu'il sera choisi (cela devrait arriver vers la mi-2012).

3. Sources

Un ordinateur est une machine déterministe. Pour obtenir une part d'aléatoire, il faut y mêler le résultat de certaines mesures du monde physique.

Une note philosophique : à un moment donné, il faut faire confiance à des personnes intelligentes, celles qui portent des blouses de laboratoire ou qui sont payées pour faire de la recherche fondamentale. Lorsque vous utilisez une fonction de hachage telle que SHA-256, vous faites en fait confiance à un groupe de cryptographes lorsqu'ils vous disent : nous avons cherché des failles, très fort, et pendant plusieurs années, et n'en avons trouvé aucune. Lorsque vous utilisez un morceau de matière radioactive en décomposition avec un compteur Geiger, vous faites confiance à des physiciens qui vous disent : nous avons cherché très fort des moyens de prédire quand le prochain noyau atomique explosera, mais nous n'en avons trouvé aucun. Notez que, dans ce cas précis, les "physiciens" sont des gens comme Becquerel, Rutherford, Bohr ou Einstein, et que "vraiment difficile" signifie "plus d'un siècle de recherche accumulée", donc vous n'êtes pas exactement en territoire inconnu. Pourtant, il y a encore un peu de foi dans la sécurité.

Certains ordinateurs comprennent déjà du matériel qui génère des données aléatoires (c'est-à-dire qui utilise et mesure un processus physique qui, d'après les physiciens, est suffisamment aléatoire). Le VIA C3 (une ligne de CPU compatibles x86) possède un tel matériel. Étrangement, le Commodore 64, ordinateur familial d'il y a 30 ans, disposait également d'un RNG matériel (c'est du moins ce qu'on dit). Wikipedia au moins).

Sauf matériel spécial, vous devez utiliser tous les événements physiques que vous pouvez obtenir. Typiquement, vous utiliserez les frappes au clavier, les paquets Ethernet entrants, les mouvements de souris, les accès au disque dur... chaque événement est accompagné de données et se produit à un instant mesurable (les processeurs modernes ont des horloges très précises, grâce aux compteurs de cycles). Ces instants, et le contenu des données de l'événement, peuvent être accumulés comme des sources d'entropie. Ceci est beaucoup plus facile pour le système d'exploitation lui-même (qui a un accès direct au matériel) que pour les applications, donc la façon normale de collecter une graine est de demander au système d'exploitation (sous Linux, cela s'appelle /dev/random ou /dev/urandom (les deux ont des avantages et des problèmes, choisissez votre poison) ; sous Windows, appelez CryptGenRandom() ).

Un cas extrême est celui des applets Java d'avant la version 1.2, avant l'ajout de la fonction java.security.SecureRandom ; comme Java est très efficace pour isoler le code d'application du matériel, obtenir une graine aléatoire était un défi difficile à relever. La solution habituelle était d'avoir deux ou trois threads fonctionnant simultanément et changeant follement de thread, de sorte que le nombre de changements de threads par seconde soit quelque peu aléatoire (en fait, cela tente d'extraire le caractère aléatoire à travers le timing des actions du planificateur du système d'exploitation, qui dépendent de ce qui se passe également sur la machine, y compris les événements liés au matériel). Ce n'était pas du tout satisfaisant.

Un problème avec les mesures liées au temps est que l'attaquant sait également quelle est l'heure actuelle. Si l'attaquant a un accès applicatif à la machine, il peut également lire le compteur de cycles.

Certaines personnes ont proposé d'utiliser les cartes audio comme sources de "bruit blanc" en réglant l'amplificateur à son maximum (même les serveurs ont de l'audio de nos jours). D'autres plaident pour la mise sous tension des webcams (nous savons que les vidéos des webcams sont "bruyantes" et que c'est bon pour le hasard, même si la webcam est face à un mur) ; mais les serveurs avec webcams ne sont pas courants. Vous pouvez également envoyer un ping à un serveur de réseau externe (par ex. www.google.com ) et voir combien de temps il met à revenir (mais cela pourrait être observé par un attaquant espionnant le réseau).

La beauté de l'étape de mélange, avec une fonction de hachage, est que l'entropie ne peut que s'accumuler ; il n'y a aucun mal à ajouter des données, même si ces données ne sont pas si aléatoires. Il suffit de faire passer autant de données que possible par la fonction de hachage. Les fonctions de hachage sont assez rapides (une bonne implémentation de SHA-512 traitera plus de 150 Mo/s sur un PC typique, en utilisant un seul cœur) et l'ensemencement ne se produit pas si souvent.

4. Conclusion

Utilisez un HSM . Ils coûtent quelques centaines ou milliers de dollars, mais vos secrets ne valent-ils pas beaucoup plus que cela ? Un HSM comprend du matériel RNG, exécute l'algorithme PRNG et stocke la graine avec une résistance à la falsification. En outre, la plupart des HSM sont déjà certifiés au regard de diverses réglementations nationales (par exemple, FIPS 140 aux États-Unis et les niveaux EAL en Europe).

Si vous êtes si bon marché que vous n'achèterez pas de HSM, ou si vous voulez protéger des données qui n'ont pas beaucoup de valeur, construisez un PRNG cryptographiquement sûr en utilisant une graine obtenue par hachage. lots de mesures physiques. Tout ce qui provient d'un matériel doit être haché, ainsi que l'instant (lire "compteur de cycles") auquel ces données ont été obtenues. Vous devriez hacher les données par mégaoctet ici. Ou, mieux encore, faites pas le faire : il suffit d'utiliser les facilités offertes par votre système d'exploitation, qui inclut déjà un tel code.

48voto

Dean Povey Points 4761

La graine la plus sûre est celle qui a le plus haut niveau d'entropie (ou le plus grand nombre de bits qui ne peuvent être prédits). L'heure est généralement une mauvaise graine car elle a une faible entropie (c'est-à-dire que si vous savez quand la transaction a eu lieu, vous pouvez deviner l'heure à quelques bits près). Les sources d'entropie matérielles (par exemple, les processus de désintégration) sont très bonnes car elles produisent un bit d'entropie pour chaque bit de semence.

En général, une source matérielle n'est pas pratique pour la plupart des besoins, ce qui vous amène à compter sur le mélange d'un certain nombre de sources d'entropie de faible qualité pour produire une source plus élevée. Pour ce faire, on estime le nombre de bits d'entropie pour chaque échantillon, puis on rassemble suffisamment d'échantillons pour que l'espace de recherche de la source d'entropie soit suffisamment grand pour qu'un attaquant ne puisse pas y effectuer de recherche (128 bits est une bonne règle empirique).

Parmi les sources que vous pouvez utiliser, citons : l'heure actuelle en microsecondes (généralement une entropie très faible de 1/2 bit selon la résolution et la facilité avec laquelle un attaquant peut la deviner), le temps d'interarrivée des événements de l'interface utilisateur, etc.

Les sources du système d'exploitation telles que /dev/random et le générateur de nombres aléatoires CAPI de Windows fournissent souvent une source pré-mélangée de ces sources à faible entropie, par exemple le générateur Windows CryptGenRandom comprend :

  • L'ID du processus actuel (GetCurrentProcessID).
  • L'ID du thread actuel (GetCurrentThreadID).
  • Le nombre de tics depuis le démarrage (GetTickCount).
  • L'heure actuelle (GetLocalTime).
  • Divers compteurs de performance de haute précision compteurs de performance (QueryPerformanceCounter).-
  • Un hachage MD4 de l'environnement de l'utilisateur. de l'utilisateur, qui comprend le nom d'utilisateur, le nom de l'ordinateur et le chemin de recherche. [...]-
  • Compteurs internes de haute précision du CPU, tels que RDTSC, RDMSR, RDPMC.

Certains PRNG ont des stratégies intégrées qui permettent de mélanger l'entropie de sources de faible qualité pour produire des résultats de haute qualité. Un très bon générateur est le Fortuna générateur. Il utilise spécifiquement des stratégies qui limitent le risque si l'une des sources d'entropie est compromise.

14voto

Vinko Vrsalovic Points 116138

La graine la plus sûre est une graine véritablement aléatoire, que l'on peut approcher dans les systèmes informatiques pratiques d'aujourd'hui en utilisant une liste de degrés de confiance décroissants :

  • Matériel spécial
  • Installations fournies par votre système d'exploitation qui tentent de capturer des événements chaotiques comme les lectures de disque et les mouvements de souris (/dev/random). Une autre option sur cette ligne "capturer les événements imprévisibles" est d'utiliser un processus ou une machine indépendante qui capture ce qui lui arrive comme un pool d'entropie, au lieu du générateur de nombres aléatoires "sécurisé" fourni par le système d'exploitation, pour un exemple, voir EntropyPool
  • Utiliser une mauvaise graine (c'est-à-dire le temps) et la combiner avec d'autres données que vous seul connaissez (par exemple, hacher le temps avec un secret et d'autres critères tels que les PID ou l'état interne de l'application/OS, afin qu'il n'augmente et ne diminue pas nécessairement en fonction du temps).

7voto

msw Points 25319

Un exemple intéressant de tampon à usage unique : lorsque je fais de l'espionnage, j'ai un système qui me permet de ne communiquer que quelques lettres. Par exemple, la dernière fois que j'ai vendu des plans secrets de fabrication de grille-pain au duché de Grand Fenwick, je n'ai eu besoin que de chuchoter :

enonH

à ma confédérée. Elle savait que pour obtenir http://is.gd/enonH- (il s'agit d'une URL d'extension "sûre" qui vous conduit à la page d'extension is.gd qui, à son tour, pointe vers une image complètement SFW d'une grenouille). Cela nous a donné 409k bits de tampon à usage unique ou - si je fais un clin d'œil en murmurant "enonH" - elle sait qu'elle peut prendre le hachage de l'image et l'utiliser comme clé de décodage pour ma prochaine transmission.

En raison de la compression des images JPEG, elles ont tendance à être de relativement bonnes sources d'entropie, comme l'indiquent les rapports suivants ent :

$ ent grenouille.jpg
Entropie = 7,955028 bits par octet.

Une compression optimale réduirait la la taille de ce fichier de 51092 octets de 0 pour cent.

La distribution du chi carré pour 51092 échantillons est de 4409,15, et le hasard ferait que dépasser cette valeur 0,01 % des fois. fois.

La moyenne arithmétique des octets de données est de 129.0884 (127.5 = aléatoire).
La valeur de Monte Carlo pour Pi est 3.053435115 (erreur 2,81 %).
Le coefficient de corrélation sérielle est de 0,052738 (totalement non corrélée = 0,0).non corrélée = 0,0).

Si l'on ajoute à cela l'image presque impossible à deviner vers laquelle je l'ai dirigée, mes projets secrets de grille-pain sont à l'abri de l'homme.

6voto

Rook Points 34698

La réponse est /dev/random sur une machine Linux. Ceci est très proche d'un "vrai" générateur de nombres aléatoires, où comme /dev/urandom peut être générée par un PRNG si la réserve d'entropie est épuisée. La citation suivante est tirée du Le fichier random.c du noyau Linux Tout ce dossier est une belle lecture, plein de commentaires. Le code lui-même a été adopté à partir de PGP. Sa beauté n'est pas limitée par les contraintes du C, qui est marqué par des structures globales enveloppées par des accesseurs. C'est une conception tout simplement impressionnante.

Cette routine rassemble les bruits de l'environnement des pilotes de périphériques, etc. renvoie de bons nombres aléatoires, adaptés pour une utilisation cryptographique. Outre les cryptographiques évidentes, ces nombres nombres sont également bons pour l'ensemencement les numéros de séquence TCP, et d'autres endroits où il est souhaitable d'avoir des nombres qui ne sont pas seulement aléatoires, mais difficiles à prédire par un attaquant.

Théorie du fonctionnement

Les ordinateurs sont des appareils très prévisibles. Il est donc extrêmement difficile
pour produire des nombres vraiment aléatoires sur un ordinateur --- par opposition à
des nombres pseudo-aléatoires, qui peuvent facilement générés en utilisant un
algorithme. Malheureusement, il est très facile pour les attaquants de deviner la séquence de nombres pseudo-aléatoires et, pour certains
applications, ce n'est pas acceptable. Donc, à la place, nous devons essayer de rassembler le "bruit environnemental" de l'environnement l'environnement de l'ordinateur, qui doit être difficile à observer pour les attaquants extérieurs d'observer, et l'utiliser pour générer des nombres aléatoires. Dans un environnement Unix le mieux est de le faire depuis à l'intérieur du noyau.

Les sources d'aléa provenant de l'environnement incluent les claviers entre eux.
temporisations, les temporisations inter-interruptions de certaines interruptions, et d'autres événements qui sont à la fois (a) non déterministes et (b) difficiles à mesurer pour un observateur extérieur de mesurer. Les aléas provenant de ces sources sont ajoutés à un "pool d'entropie qui est mélangé à l'aide d'une fonction de type CRC. de type CRC. Cette fonction n'est pas cryptographiquement forte, mais elle est adéquat en supposant que le caractère aléatoire n'est pas choisi de façon malveillante, et c'est assez rapide assez rapide pour que la surcharge de le faire à chaque interruption est très raisonnable. Comme les octets aléatoires sont mélangés dans le pool d'entropie, les routines conservent une estimation du nombre de bits de aléatoires ont été stockés dans le dans l'état interne du générateur de nombres aléatoires. interne du générateur de nombres aléatoires.

Lorsque des octets aléatoires sont souhaités, ils sont obtenus en prenant le SHA
hachage du contenu de l'"entropy d'entropie". Le hachage SHA évite d'exposer l'état interne de l'entropie d'entropie. On pense qu'il est infaisable sur le plan informatique de dériver toute information utile sur l'entrée l'entrée du SHA à partir de sa sortie. Même si il est possible d'analyser SHA de manière intelligente, tant que la quantité de données de données retournées par le générateur est inférieure à l'entropie inhérente à l'algorithme SHA.
la piscine, les données de sortie sont totalement imprévisibles. Pour cette raison, la routine diminue son estimation interne interne de combien de bits de "vrai aléatoire" sont contenus dans le d'entropie au fur et à mesure qu'elle produit des aléatoires. Si cette estimation atteint zéro, la routine peut toujours générer des nombres aléatoires. aléatoires ; cependant, un attaquant peut (au moins en (du moins en théorie) être capable de déduire la future sortie du générateur à partir des sorties antérieures. Cela nécessite une cryptanalyse réussie de SHA, qui ce qui n'est pas considéré comme faisable, mais il existe une faible possibilité. Néanmoins, ces chiffres devraient être utiles pour la grande majorité des majorité des cas.

...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X