Je comprends le fonctionnement des générateurs de nombres aléatoires standard. Mais lorsque vous travaillez avec la cryptographie, les nombres aléatoires doivent vraiment être aléatoires.
Je sais qu'il existe des instruments qui lisent bruit blanc cosmique pour aider à générer des hachages sécurisés, mais votre PC standard n'en a pas.
Comment un générateur de nombres aléatoires cryptographiquement sécurisé obtient-il ses valeurs sans modèles répétables?
Un générateur aléatoire de nombres cryptographiquement sécurisé, comme vous pouvez l'utiliser pour générer des clés de chiffrement, fonctionne en rassemblant l'entropie - c'est-à-dire une entrée imprévisible - à partir d'une source que d'autres personnes ne peuvent pas observer.
Par exemple,/dev/random (4) sur Linux recueille des informations sur la variation de la synchronisation des interruptions matérielles à partir de sources telles que les disques durs renvoyant des données, les pressions sur les touches et les paquets réseau entrants. Cette approche est sécurisée à condition que le noyau ne surestime pas la quantité d'entropie qu'il a collectée. Il y a quelques années, les estimations de l'entropie des différentes sources ont toutes été réduites, ce qui les rend beaucoup plus conservatrices. Voici une explication de la façon dont Linux estime l'entropie .
Rien de ce qui précède n'est particulièrement haut débit./dev/random (4) est probablement sécurisé, mais il maintient cette sécurité en refusant de donner des données une fois qu'il ne peut pas être sûr que ces données sont aléatoires en toute sécurité. Si vous souhaitez, par exemple, générer un lot de clés cryptographiques et de nonces, vous voudrez probablement recourir à des générateurs de nombres aléatoires matériels.
Souvent, les RNG matériels sont conçus pour échantillonner à partir de la différence entre une paire d'oscillateurs qui fonctionnent à peu près à la même vitesse, mais dont les taux varient légèrement en fonction du bruit thermique. Si je me souviens bien, le générateur de nombres aléatoires utilisé pour la loterie d'obligations à prime du Royaume-Uni, ERNIE, fonctionne de cette façon.
D'autres schémas incluent l'échantillonnage du bruit sur un CCD (voir lavaRND ), la désintégration radioactive (voir hotbits ) ou le bruit atmosphérique (voir random.org , ou branchez simplement une radio AM réglée ailleurs qu’une station sur votre carte son). Ou vous pouvez directement demander à l'utilisateur de l'ordinateur de frapper sur son clavier comme un chimpanzé dérangé pendant une minute, quoi que flotte votre bateau.
Comme l'a souligné andras, je n'ai pensé qu'à parler de certains des schémas de collecte d'entropie les plus courants. réponse de Thomas Pornin et réponse de Johannes Rössel font tous les deux du bon travail pour expliquer comment on peut manipuler l'entropie collectée afin d'en remettre des morceaux.
À des fins cryptographiques, ce qui est nécessaire, c'est que le flux soit "indiscernable du point de vue informatique des bits uniformément aléatoires". "Computationnellement" signifie qu'il n'a pas besoin d'être vraiment aléatoire, seulement qu'il apparaît ainsi à toute personne n'ayant pas accès au propre ordinateur de Dieu.
En pratique, cela signifie que le système doit d'abord rassembler une séquence de n bits vraiment aléatoires. n doit être suffisamment grand pour contrecarrer la recherche exhaustive, c'est-à-dire qu'il est impossible de tout essayer 2 ^ n combinaisons de n bits. Ceci est réalisé, en ce qui concerne la technologie d'aujourd'hui, tant que n est supérieur à 90 environ, mais les cryptographes ne font que aime des puissances de deux, il est donc d'usage d'utiliser n = 128 .
Ces n bits aléatoires sont obtenus en rassemblant des "événements physiques" qui devraient être imprévisibles en ce qui concerne la physique. Habituellement, le timing est utilisé: le CPU a un compteur de cycle qui est mis à jour plusieurs milliards de fois par seconde, et certains événements se produisent avec une quantité inévitable de gigue (paquets réseau entrants, mouvements de souris, frappes de touches ...). Le système code ces événements puis les "comprime" en appliquant une fonction de hachage cryptographiquement sécurisée telle que SHA-256 (la sortie est ensuite tronquée pour donner notre n morceaux). Ce qui importe ici, c'est que l'encodage des événements physiques ait suffisamment d'entropie : grosso modo, que lesdits événements auraient pu collectivement supposer au moins 2 ^ n combinaisons. La fonction de hachage, par sa définition, devrait faire un bon travail pour concentrer cette entropie dans une chaîne de bits n .
Une fois que nous avons n bits, nous utilisons un PRNG (générateur de nombres pseudo-aléatoires) pour lancer autant de bits A PRNG est censé être sécurisé sur le plan cryptographique si, en supposant qu'il fonctionne sur une zone suffisamment inconnue n -bit key, sa sortie ne peut pas être distinguée par calcul de bits uniformément aléatoires. Dans les années 90, un choix populaire était RC4 , qui est très simple à mettre en œuvre et assez rapide. Cependant, il s'est avéré les biais, c'est-à-dire qu'il n'était pas aussi indiscernable qu'on le souhaitait initialement. Le Projet eSTREAM consistait à rassembler des conceptions plus récentes pour PRNG (en fait des chiffrements de flux, car la plupart des chiffrements de flux sont constitués dans un PRNG, dont la sortie est XORed avec les données à crypter), les documentant et favorisant l'analyse par les cryptographes. Le portefeuille eSTREAM contient sept PRNG conceptions qui ont été jugées suffisamment sécurisées (c'est-à-dire qu'elles ont résisté à l'analyse et les cryptographes ont tendance à bien comprendre g de pourquoi ils ont résisté). Parmi eux, quatre sont "optimisés pour les logiciels". La bonne nouvelle est que même si ces nouveaux PRNG semblent être beaucoup plus sûrs que RC4, ils sont aussi nettement plus rapides (nous parlons ici de centaines de mégaoctets par seconde). Trois d'entre eux sont "gratuit pour toute utilisation" et le code source est fourni.
Du point de vue de la conception, PRNG réutilise une grande partie des éléments des blocs de chiffrement. Les mêmes concepts d'avalanche et de diffusion de bits dans un large état interne sont utilisés. Alternativement, un décent PRNG peut être construit à partir d'un chiffrement par bloc: utilisez simplement la séquence de bits n ) comme clé dans un chiffrement par bloc et chiffrez successivement valeurs d'un compteur (exprimées en m - séquence de bits, si le chiffrement par bloc utilise m - blocs de bits) .Cela produit un flux pseudo-aléatoire de bits qui ne peut pas être distingué par calcul du hasard, tant que le chiffrement de bloc est sécurisé et que le flux produit ne dépasse pas m * 2 ^ (m/2) bits (pour m = 128 , cela signifie environ 300 milliards de gigaoctets, donc c'est assez grand pour la plupart des utilisations.) Ce type d'utilisation est connu sous le nom de mode compteur (CTR) .
Habituellement, un chiffrement par blocs en mode CTR n'est pas aussi rapide qu'un chiffrement de flux dédié (le but du chiffrement de flux est qu'en perdant la flexibilité d'un chiffrement par blocs, de meilleures performances sont attendues). Cependant, si vous avez l'un des processeurs Intel les plus récents avec les instructions AES-NI (qui sont essentiellement une implémentation AES dans le matériel, intégrée dans le CPU), alors AES avec le mode CTR sera produire une vitesse imbattable (plusieurs gigaoctets par seconde).
Tout d'abord, l'intérêt d'un cryptage sécurisé PRNG n'est pas de générer des séquences entièrement imprévisibles. Comme vous l'avez noté, l'absence de quelque chose qui génère de grands volumes de (plus ou moins) vrai hasard1 rend cela impossible.
Vous avez donc recours à quelque chose qui est seulement difficile à prévoir. "Difficile" signifie ici que cela prend un temps irréalisable, moment où tout ce qui était nécessaire serait de toute façon obsolète. Il existe un certain nombre d'algorithmes mathématiques qui jouent un rôle dans ce processus - vous pouvez avoir un aperçu si vous prenez des CSPRNG bien connus et regardez comment ils fonctionnent.
Les variantes les plus courantes pour construire un tel PRNG sont:
Les fonctions de hachage sur un compteur sont également parfois utilisées. Wikipedia a plus à ce sujet .
Les exigences générales sont simplement qu'il est impossible de déterminer le vecteur d'initialisation d'origine à partir du flux binaire d'un générateur et que le bit suivant ne peut pas être facilement prédit.
En ce qui concerne l'initialisation, la plupart des CSPRNG utilisent diverses sources disponibles sur le système, allant de choses vraiment aléatoires comme le bruit de ligne, les interruptions ou d'autres événements dans le système à d'autres choses comme certains emplacements de mémoire, etc. Le vecteur d'initialisation est de préférence vraiment aléatoire et ne dépend pas d'un algorithme mathématique. Cette initialisation a été interrompue pendant un certain temps dans la mise en œuvre Debian d'OpenSSL, ce qui a entraîné de graves problèmes de sécurité.
1 Ce qui a aussi ses problèmes et il faut faire attention à éliminer les biais car des choses comme le bruit thermique ont des caractéristiques différentes en fonction de la température - vous avez presque toujours des biais et vous devez les éliminer. Et ce n'est pas une tâche insignifiante en soi.
Pour qu'un générateur de nombres aléatoires soit pris en compte cryptographiquement sécurisé, il doit être protégé contre les attaques d'un adversaire qui connaît l'algorithme et un (grand) nombre de bits générés précédemment. Cela signifie que quelqu'un avec ces informations ne peut pas reconstruire l'état interne caché du générateur et donner des prédictions de ce que seront les prochains bits produits avec une précision meilleure que 50%.
Les générateurs de nombres pseudo-aléatoires normaux ne sont généralement pas sécurisés cryptographiquement, car la reconstruction de l'état interne à partir de bits précédemment sortis est généralement triviale (souvent, l'état interne entier n'est que les N derniers bits produits directement). Tout générateur de nombres aléatoires sans bonnes propriétés statistiques n'est pas non plus cryptographiquement sécurisé, car sa sortie est au moins prévisible même sans connaître l'état interne.
Ainsi, quant à leur fonctionnement, tout bon système de cryptage peut être utilisé comme générateur de nombres aléatoires sécurisé sur le plan cryptographique - utilisez le système de cryptage pour crypter la sortie d'un générateur de nombres aléatoires `` normal ''. Puisqu'un adversaire ne peut pas reconstruire la sortie en texte brut du générateur de nombres aléatoires normal, il ne peut pas l'attaquer directement. Il s'agit d'une définition quelque peu circulaire et pose la question de savoir comment vous devez sécuriser le système de chiffrement pour le sécuriser, ce qui est un tout autre problème.
Chaque générateur utilisera sa propre stratégie d'amorçage, mais voici un peu de la documentation de l'API Windows sur CryptGenRandom
Avec les CSP Microsoft, CryptGenRandom utilise le même générateur de nombres aléatoires que celui utilisé par les autres composants de sécurité. Cela permet à de nombreux processus de contribuer à une graine à l'échelle du système. CryptoAPI stocke une graine aléatoire intermédiaire avec chaque utilisateur. Pour former le germe du générateur de nombres aléatoires, une application appelante fournit des bits qu'elle pourrait avoir - par exemple, une entrée de synchronisation de souris ou de clavier - qui sont ensuite combinés à la fois avec le germe stocké et diverses données système et données utilisateur telles que l'ID de processus et ID de thread, horloge système, heure système, compteur système, état de la mémoire, clusters de disques libres, bloc d'environnement utilisateur haché. Ce résultat est utilisé pour amorcer le générateur de nombres pseudo-aléatoires (PRNG).
Dans Windows Vista avec Service Pack 1 (SP1) et versions ultérieures, une implémentation du contre-mode AES basé sur PRNG spécifié dans la publication spéciale NIST 800-90 est utilisée. Dans Windows Vista, Windows Storage Server 2003 et Windows XP, le PRNG spécifié dans la norme FIPS) 186-2 est utilisé. Si une application a accès à une bonne source aléatoire, elle peut remplir le tampon pbBuffer avec certaines données aléatoires avant d'appeler CryptGenRandom. Le CSP utilise ensuite ces données pour randomiser davantage sa graine interne. Il est acceptable d'omettre l'étape d'initialisation du tampon pbBuffer avant d'appeler CryptGenRandom.