CVE-2021-41117
Génération non sécurisée de nombres aléatoires
- Publié
- 11 oct. 2021
- Mise à jour
- 4 août 2024
- Attribution de CNA
- GitHub_M
- Preuve observée
- 8 août 2026
CVSS primaire
nvd · CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:NFaible · 30 prochains jours
- Percentile
- 87,1 %
- Date du modèle
- 21 sept. 2026
EPSS est une estimation statistique, et non une certitude ou une mesure d'impact. Combinez-le avec CVSS, le statut KEV, l'exposition et votre environnement.
Résumé
keypair est un générateur de clés RSA PEM écrit en JavaScript. keypair implémente beaucoup de primitives cryptographiques lui-même ou en empruntant à d'autres bibliothèques lorsque c'est possible, notamment node-forge. Un problème a été découvert : cette bibliothèque générait des clés RSA identiques utilisées dans SSH. Cela signifierait que la bibliothèque génère des valeurs P, Q (et donc N) identiques, ce qui, en pratique, est impossible avec des clés RSA-2048. Générer des valeurs identiques, de manière répétée, indique généralement un problème de génération de nombres aléatoires de mauvaise qualité, ou une mauvaise gestion de la sortie du CSPRNG. Problème 1 : Mauvaise génération de nombres aléatoires (`GHSL-2021-1012`). La bibliothèque ne repose pas entièrement sur un CSPRNG fourni par la plateforme ; elle utilise plutôt sa propre approche CMAC basée sur un compteur. Là où les choses tournent mal, c'est lors de l'ensemencement de l'implémentation CMAC avec des données « vraiment » aléatoires dans la fonction `defaultSeedFile`. Afin d'ensemencer le générateur AES-CMAC, la bibliothèque adopte deux approches différentes selon l'environnement d'exécution JavaScript. Dans un navigateur, la bibliothèque utilise [`window.crypto.getRandomValues()`](https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L971). Cependant, dans un environnement d'exécution NodeJS, l'objet `window` n'est pas défini, elle suit donc une solution beaucoup moins sécurisée, qui contient également un bug. Il semble bien que la bibliothèque essaie d'utiliser le CSPRNG de Node lorsque c'est possible ; malheureusement, il semble que l'objet `crypto` soit nul parce qu'une variable portant le même nom a été déclarée et définie à `null`. Le chemin du CSPRNG de Node n'est donc jamais emprunté. Cependant, lorsque `window.crypto.getRandomValues()` n'est pas disponible, un générateur de nombres aléatoires Lehmer LCG est utilisé pour ensemencer le compteur CMAC, et le LCG est ensemencé avec `Math.random`. Bien que ce soit médiocre et que cela constituerait probablement un bug de sécurité en soi, cela n'explique pas la fréquence extrême à laquelle des clés en double apparaissent. Le défaut principal : la sortie du Lehmer LCG est encodée incorrectement. La [ligne][https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L1008] spécifique contenant le défaut est : `b.putByte(String.fromCharCode(next & 0xFF))`. La [définition](https://github.com/juliangruber/keypair/blob/87c62f255baa12c1ec4f98a91600f82af80be6db/index.js#L350-L352) de `putByte` est `util.ByteBuffer.prototype.putByte = function(b) {this.data += String.fromCharCode(b);};`. En simplifiant, cela donne `String.fromCharCode(String.fromCharCode(next & 0xFF))`. Le double `String.fromCharCode` est presque certainement involontaire et constitue la source d'un ensemencement faible. Malheureusement, cela ne produit pas d'erreur. Cela a plutôt pour conséquence que la majeure partie du tampon contient des zéros. Comme nous masquons avec 0xFF, nous pouvons déterminer que 97 % de la sortie du LCG est convertie en zéros. Les seules sorties qui produisent des valeurs significatives sont les sorties 48 à 57 incluses. L'impact est que chaque octet de la graine du RNG a 97 % de chances d'être 0 en raison d'une conversion incorrecte. Lorsque ce n'est pas le cas, les octets vont de 0 à 9. En résumé, il y a trois préoccupations immédiates : 1. La bibliothèque dispose d'un chemin de secours non sécurisé pour les nombres aléatoires. Idéalement, la bibliothèque exigerait un CSPRNG fort au lieu de tenter d'utiliser un LCG et `Math.random`. 2. La bibliothèque n'utilise pas correctement un générateur de nombres aléatoires fort lorsqu'elle est exécutée dans NodeJS, alors même qu'un CSPRNG fort est disponible. 3. Le chemin de secours présente un problème dans l'implémentation : la majorité des données de la graine seront effectivement des zéros. En raison de la mauvaise génération de nombres aléatoires, keypair génère des clés RSA relativement faciles à deviner. Cela pourrait permettre à un attaquant de déchiffrer des messages confidentiels ou d'obtenir un accès autorisé à un compte appartenant à la victime.
Utilisation responsable
Utilisez les informations de vulnérabilité uniquement sur les systèmes que vous possédez ou que vous êtes autorisé à tester. Kitploit renvoie aux métadonnées de la recherche publique et ne stocke pas de code d'exploitation ni de charges utiles malveillantes.