Il me semble qu'un composant matériel qui génère des nombres aléatoires est extrêmement simple - il suffit de mesurer de minuscules vibrations dans le matériel avec un capteur, non? Peut-être que je me trompe, mais il semble que si vous mesuriez les vibrations avec une très grande précision, vous pourriez facilement générer des nombres aléatoires non devinables.
Cependant, je suis un noob en cryptographie et j'en sais peu. Je lis donc et n article dit:
et vous n'avez pas besoin d'être aussi sophistiqué pour affaiblir un générateur de nombres aléatoires. Ces générateurs sont déjà étonnamment fragiles, et il est extrêmement difficile de détecter quand un est cassé. Les responsables de Debian ont magnifiquement souligné ce point en 2008 lorsqu'un nettoyage de code erroné a réduit l'entropie effective d'OpenSSL à seulement 16 bits. En fait, les RNG sont si vulnérables que le défi ici n'est pas d'affaiblir le RNG - n'importe quel idiot avec un clavier peut le faire - il le fait sans rendre l'implémentation trivialement vulnérable pour tout le monde.
Je manque sûrement des détails critiques sur la façon dont la génération de nombres aléatoires est "fragile". Quelqu'un peut-il expliquer?
La première chose que vous mentionnez est une source de bruit matériel. La mesure de haute précision de certains phénomènes métastables est suffisante pour générer des données imprévisibles. Cela peut être fait avec une diode zener polarisée en inverse, avec des oscillateurs en anneau, avec un ADC, ou même avec un compteur Geiger. Cela peut même être fait en mesurant les retards de nanosecondes dans le temps entre les frappes. Ces sources de bruit peuvent échouer si le matériel lui-même commence à tomber en panne. Par exemple, un transistor peut tomber en panne s'il n'est pas spécifiquement conçu pour fonctionner en sens inverse à haute tension. Bien que ces techniques présentent des niveaux de fragilité variables, ce n'est pas ce qui est discuté dans le texte que vous avez cité.
Le deuxième type de RNG que vous mentionnez est un logiciel RNG appelé générateur de nombres pseudo-aléatoires (PRNG*). Il s'agit d'un algorithme qui prend un seed, qui est comme une clé de cryptage, et le développe en un flux de données sans fin. Il essaie de garantir que les données ne peuvent pas être prédites ou divulguées en dehors du hasard pur, sans connaître la graine aléatoire secrète avec laquelle l'algorithme a commencé. Dans ce cas, le PRNG est implémenté dans un logiciel pur, donc le casser ne prend que l'introduction d'un bogue dans le code, ce dont parle le texte que vous avez cité. C'est simplement du code qui est fragile, risquant un échec complet si des modifications du code s'écartent du comportement prévu de l'algorithme.
A PRNG peut être considéré comme un algorithme de chiffrement réutilisé. En fait, vous pouvez créer un cryptographiquement sécurisé PRNG en utilisant un chiffrement comme AES pour chiffrer un compteur. Tant que la clé de chiffrement (valeur de départ) est secrète, la sortie ne peut pas être prédite et la valeur de départ ne peut pas être découverte. Lorsque vous y réfléchissez de cette façon, il devient plus facile de comprendre comment une petite modification sans conséquence du code peut briser complètement la sécurité de l'algorithme.
Alors, comment les appareils modernes collectent-ils réellement le hasard? Prenons un serveur fonctionnant tranquillement dans un centre de données quelque part. Pour prendre en charge des choses comme TLS, il a besoin d'une grande quantité de données complètement imprévisibles qui ne peuvent pas être distinguées d'un flux vraiment aléatoire. Sans source de bruit matériel dédiée, le caractère aléatoire doit provenir de l'intérieur. Les ordinateurs s'efforcent d'être entièrement déterministes, mais ils ont beaucoup d'entrée provenant de dispositifs non déterministes. Entrez ... interrompt!
Dans le matériel moderne, un interruption est un signal émis par le matériel pour alerter le CPU d'un changement d'état. Il permet au CPU d'éviter d'interroger rapidement chaque périphérique matériel pour les mises à jour et de croire à la place que le périphérique l'alerte de manière asynchrone le moment venu. Lorsqu'une interruption se produit, un gestionnaire d'interruption est appelé pour traiter le signal. Il s'avère que ce gestionnaire est l'endroit idéal pour obtenir le hasard! Lorsque vous mesurez la synchronisation au niveau nanoseconde des interruptions, vous pouvez rapidement obtenir un peu d'aléatoire. En effet, les interruptions sont déclenchées pour toutes sortes de choses, des paquets arrivant sur le NIC aux données lues sur un disque dur. Certaines de ces sources d'interruption sont très non déterministes, comme un disque dur entraînement qui repose sur le mouvement physique d'un actionneur.
Une fois que suffisamment de bits aléatoires ont été collectés par le système d'exploitation, une petite graine d'au moins 128 bits peut être introduite dans un système de sécurité cryptographique PRNG pour générer un flux illimité de données pseudo-aléatoires. À moins que quelqu'un ne puisse prédire exactement à chaque interruption passée, avec une précision de l'ordre de la nanoseconde, ils ne pourront pas dériver la graine et ne pourront pas prédire la sortie future PRNG. Cela rend la sortie tout à fait adaptée aux clés TLS.
* Un orienté sécurité PRNG est appelé un PRNG cryptographiquement sécurisé, ou CSPRNG. L'utilisation d'un PRNG normal lorsqu'une application appelle un CSPRNG peut entraîner une sécurité) vulnérabilités.
Historiquement, les RNG matériels adaptés à la cryptographie n'étaient pas couramment disponibles sur le PC: par exemple, selon cette question AMD n'a ajouté la prise en charge qu'il y a quelques années, donc même aujourd'hui, un fournisseur de logiciels ne peut pas simplement supposer qu'il sera disponible. C'est probablement pourquoi OpenSSL (comme indiqué dans votre citation) utilisait un logiciel RNG, le rendant vulnérable au bogue trouvé dans le code.
(Comme discuté en détail dans les commentaires, un PC standard contient un certain nombre de "sources d'entropie" qu'un RNG logiciel peut utiliser - et je crois que OpenSSL le fait, bien que je ne le sois pas très familier - mais évidemment dans ce scénario un bogue dans le logiciel peut entraîner de mauvais nombres aléatoires, comme cela s'est effectivement produit.)
Il y a aussi craint que les RNG matériels aient pu être détournés , ce qui amène les gens à combiner les RNG matériels avec d'autres sources d'entropie plutôt que de les utiliser tels quels. (Le matériel avec porte dérobée est également mentionné dans votre article lié, à quelques paragraphes du bit que vous avez cité.)
Il convient également de mentionner que les RNG matériels ne sont pas aussi simples à implémenter que votre question le suggère ... d'une part, les implémentations naïves peuvent être vulnérables à diverses attaques physiques, par exemple, si vous générez des bits aléatoires basés sur des vibrations , que se passe-t-il si quelqu'un vise une échographie? Même dans des conditions idéales, il peut y avoir une sorte de biais dans les résultats qui pourrait rendre les bits générés dangereux pour une utilisation cryptographique.
C'est pourquoi les implémentations du monde réel utilisent du bruit matériel mais aussi le traiter cryptographiquement . Mais à ce stade, vous êtes de retour à la question de savoir si l'algorithme (ou son implémentation) a été délibérément saboté, ou peut-être tout simplement pas aussi robuste qu'on le croit.
Parce qu'ils sont difficiles à tester
Bien qu'il soit facile de tester qu'un générateur de nombres aléatoires produit une sortie avec le bon format, déterminer s'il est statistiquement aléatoire est beaucoup plus complexe et peu susceptible d'être inclus dans une suite de tests automatisée. Beaucoup d'autres codes seront beaucoup plus évidents si vous le cassez.
La crypto doit avoir raison
En général, il est difficile de s'assurer que le code est correct. Une grâce économique pour beaucoup de code est que seule une petite proportion des erreurs de correction entraîne des vulnérabilités de sécurité. Mais avec le code cryptographique - y compris les générateurs de nombres aléatoires - de nombreuses erreurs de correction entraîneront des vulnérabilités. Le code cryptographique doit être correct, sécurisé et il est difficile de s'assurer qu'il est correct.
Le responsable Debian a fait une erreur majeure
Le code n'est pas vraiment fragile. Pour qu'il soit rendu insécurisé, il fallait des défaillances majeures de la part du mainteneur. Juste couper les lignes qui produisent des avertissements avec seulement des vérifications superficielles qui ne cassent rien, est assez de mauvaise qualité.
Edit: ce n'était pas seulement la faute du responsable, voir le commentaire d'Angel
L'un des aspects les plus importants de tout générateur aléatoire est que la valeur de chaque bit aléatoire doit non seulement être complètement indépendante des valeurs de tous les autres bits qu'il génère, mais elle doit également être complètement indépendante de tout le reste dans le univers qu’un adversaire pourrait observer ou influencer. Malheureusement, cette propriété est souvent l'une des plus difficiles à garantir. Le mieux que l'on puisse faire en général est de générer des bits d'une manière qui est peu susceptible d'avoir une relation exploitable avec quoi que ce soit d'autre dans l'univers.
À titre d'exemple simple, si un adversaire avec un émetteur hautement focalisé RF avait la capacité d'influencer votre générateur de nombres aléatoires afin que certains échantillons de son choix aient une probabilité de 95% d'en produire, tandis que les autres n'auraient qu'une probabilité de 5% de le faire. Si l'on devait simplement lire 128 bits d'un tel générateur et les intégrer dans une clé de 128 bits, un attaquant qui aurait concentré une attaque par force brute sur des modèles de bits proches de celui utilisé pour influencer le générateur aurait beaucoup plus de chances de réussir rapidement que si le générateur n'avait pas été biaisé. Supposons cependant qu'au lieu de choisir des bits un par un, on choisisse des groupes de 7 bits et les xor'e ensemble . Cela ferait sept fois plus de temps pour générer une clé de 128 bits, mais l'influence d'un attaquant serait réduite de 95/5 à 74/26, ce qui réduirait considérablement la probabilité que la clé finisse par être proche de la configuration binaire de l'attaquant. essayait de forcer.
Comme alternative, supposons que l'on devait générer 128 bits aléatoires, les hacher d'une certaine manière, puis les xor avec 128 autres bits aléatoires. Cela ne nécessiterait que la génération de 256 bits au lieu de 896, mais il serait très difficile pour un attaquant d'exploiter toute polarisation dans le générateur. Même si l'énumération des motifs les plus probables de 95 000 000 000 bits à 128 bits aurait environ 50% de chances de correspondre à un groupe de 128 bits utilisé avant le hachage, ou celui avec lequel la valeur de hachage était xor'ed, la distribution finale après le xor aurait peu de chances d'avoir exploitable biais ou fuite d'informations.
Les RNG sécurisés couramment utilisés comme Linux/dev/random, ChaCha20 ou RdRand fonctionnent bien pour de nombreux cas conventionnels. Cependant, ils sont loin d'être à l'épreuve des idiots. Dites que vous faites quelque chose de drôle comme ne pas configurer votre horloge en temps réel lors de la génération de nombres aléatoires au démarrage. Si vous ne comprenez pas comment cela affectera votre RNG, quelqu'un qui le fait pourrait repartir avec votre clé privée. Il y a peu de place pour l'erreur ici car une petite quantité de non-aléatoire peut compromettre un protocole cryptographique entier comme la génération de clés.
Alors que les problèmes avec des naïfs implémentations de roll-your-own de générateurs de nombres aléatoires ou d'interférences physiques dans votre matériel font de bonnes discussions, la plupart des vulnérabilités dans les nouvelles avec des générateurs de nombres aléatoires, comme le problème Debian que vous avez mentionné, sont pas en raison de ces problèmes. Les plus gros problèmes que j'ai vus à plusieurs reprises sont que les développeurs pensent qu'ils ont une bonne source d'entropie pour amorcer le générateur de nombres aléatoires alors qu'ils ne le font pas réellement, permettant par erreur de découvrir et d'exploiter l'état du générateur aléatoire, ou le manque de tests rigoureux du générateur de nombres aléatoires lui-même. Le NSA n'a pas besoin de créer de porte dérobée si vous êtes l'un des ,75% des clients TLS utilisant des clés à faible entropie. En résumé, les développeurs ignorent la peu ou pas d'avertissements et supposent que leur RNG fonctionnera dans n'importe quelle application.
Étant donné que tous les programmes informatiques produisent les mêmes sorties pour les mêmes entrées, ils doivent lire à partir d'une source d'entropie (ou de données imprévisibles) dans le système d'exploitation ou le matériel. De nos jours, nous avons des choses comme la commande RdRand qui peut générer des dizaines ou des centaines de Mo d'entropie chaque seconde. Cependant, les appareils dotés de générateurs de nombres aléatoires matériels comme le Ferranti Mark 1 en 1951 ou le Intel 82802 Firmware Hub en 1999 ont été l'exception plutôt que la règle jusqu'aux années 2010.
Ainsi, les générateurs de nombres historiquement aléatoires s'appuient sur des sources d'entropie relativement lentes comme les entrées humaines ou les temporisations informatiques, et les systèmes hérités peuvent ne pas avoir de fonctions intégrées avec de bonnes sources d'entropie disponibles. Le/dev/random de Linux, par exemple, peut utiliser le temps d'horloge de démarrage, le temps des périphériques d'entrée humains, les temps du disque, les temps IRQ et même la modification du pool d'entropie par d'autres threads
À bien des égards, les générateurs de nombres aléatoires sont fragiles car ces moyens standard d'obtenir l'entropie ne sont pas infaillibles. Tout ce qui rend ces sources d'entropie prévisibles ou limitées compromettra votre RNG, par exemple:
Souvent, les RNG n'obtiennent pas de nouvelle entropie à chaque appel de fonction comme le fait/dev/random. Parfois, vous ne pouvez pas obtenir assez d'entropie assez rapidement, ou vous ne faites pas entièrement confiance à la source d'entropie. Au lieu de cela, le RNG est ensemencé avec une source connue d'entropie, puis produit des valeurs indépendantes à partir de cette graine. Cependant, lorsque quelqu'un comprend l'état interne du générateur, les choses se passent mal, ce qui conduit à tout, de clonage de cartes à puce à tricher une machine à sous à Vegas.
Une attaque par dépassement de tampon ou une attaque similaire peut révéler l'état du générateur de nombres aléatoires. L'apprentissage de l'état peut également être possible avec une attaque par force brute, surtout si l'algorithme est connu et réversible, peut être calculé rapidement ou un texte en clair est connu. Ce fut le cas pour les problèmes avec Windows XP , bibliothèque Dropbear SSH , XorShift128 + dans Chrome , et algorithme Twister de Messerne =, parmi tant d'autres.
Exiger des mesures d'atténuation avancées pour ces attaques d'état connu rend le RNG fragile. La meilleure façon d'atténuer les attaques d'état connu est de ne pas utiliser d'algorithme vulnérable (comme la plupart des CSRNGs ). Cette question explique également plus en détail exactement ce qui sécurise un bon RNG. Cependant, même les CSRNG ont parfois aussi des faiblesses (par exemple, la vulnérabilité RNG dans le noyau Linux 2.6.1 ). La défense en profondeur nécessite donc des mesures d'atténuation telles que l'utilisation d'états séparés pour les générateurs de nombres aléatoires (peut-être un par utilisateur), le rafraîchissement fréquent de la graine et la protection contre les attaques par canal latéral et les dépassements de tampon.
Souvent, ces RNG sont fragiles en raison d'une mauvaise communication des limitations entre les développeurs de bibliothèques ou les créateurs de systèmes d'exploitation qui ne peuvent pas concevoir un système infaillible et les utilisateurs qui en attendent un. Linux, par exemple, oblige les utilisateurs à choisir entre une latence élevée/dev/aléatoire et une entropie potentiellement faible/dev/urandom. Comme autre exemple, PHP avant 5.3 ne prenait pas en charge les PRNG forts dans Windows via des interfaces telles que mcrypt_create_iv (), et avant 7.0 ne disposait pas d'un bon CSPRNG intégré.
Il y a un point de discussion populaire lorsque l'on parle de nombres aléatoires: pour un nombre vraiment aléatoire, chaque possibilité est également probable et il existe un nombre infini de modèles potentiels. Alors, comment pouvez-vous vraiment regarder une séquence et dire qu'elle n'est pas aléatoire? (Dilbert pertinent )
En réalité, la détection de modèles dans des nombres aléatoires est un domaine mature, bien qu'imparfait, et la question de savoir si le non-hasard peut être détecté a été abordée depuis que M.G. Document de Kendall et B. Babington-Smith de 1938. Vous pouvez démontrer que des types spécifiques de motifs ne sont pas beaucoup plus susceptibles d'apparaître que le hasard. Par exemple, je peux vérifier si le chiffre 1 est plus commun que les autres chiffres, avec des seuils déterminés par un test du chi carré. Tant que ces modèles testés sont au moins probables à distance et que vous vérifiez un ensemble suffisamment long de nombres générés, les chances d'un faux positif sont faibles. Bien que certains problèmes cachés avec certains générateurs de nombres aléatoires peuvent ne pas être détectés pendant des années , si vous avez effectué une cryptanalyse de base, puis appliquez des tests de qualité industrielle comme indiqué dans cette question alors vous ne peut pas se tromper.
Cependant, les concepteurs peuvent également sous-estimer leurs attaquants (comment étiez-vous censé prédire les gens effectuerait une rétro-ingénierie et chronométrerait votre machine à sous? ). Pire encore, le générateur de nombres aléatoires ou la génération d'entropie n'est jamais inspecté par un expert, et seul le résultat de l'utilisation du RNG est examiné, comme lorsque les signatures de micrologiciel PS3 ont été signées avec une sortie "aléatoire" constante .
En fin de compte, le problème ici est similaire à celui de la cybersécurité: vous disposez d'un ensemble très complexe de protocoles, d'exigences et d'appareils pour les nombres aléatoires. Comme toujours, si vous ne comprenez pas la complexité, vous êtes vulnérable à un attaquant qui le comprend.