web-dev-qa-db-fra.com

Un Rand de / dev / urandom est-il sécurisé pour une clé de connexion?

Disons que je veux créer un cookie pour un utilisateur. Générerait simplement une chaîne 1024 bit en utilisant / dev/urandom , et vérifier si elle existe déjà (en boucle jusqu'à ce que j'en obtienne une unique) suffirait?

Dois-je générer la clé en fonction d'autre chose? Est-ce sujet à un exploit d'une manière ou d'une autre?

187
Incognito

La reponse courte est oui. La réponse longue est également oui. /dev/urandom fournit des données qui ne se distinguent pas du vrai hasard, étant donné la technologie existante. Obtenir un "meilleur" caractère aléatoire que ce /dev/urandom fournit n'a pas de sens, sauf si vous utilisez l'un des rares algorithmes cryptographiques "théoriques de l'information", ce qui n'est pas votre cas (vous le savez).

La page de manuel de urandom est quelque peu trompeuse, sans doute carrément fausse, lorsqu'elle suggère que /dev/urandom peut "manquer d'entropie" et /dev/random devrait être préféré; le seul instant où /dev/urandom peut-être implique un problème de sécurité dû à une faible entropie pendant les premiers instants d'une nouvelle installation automatisée du système d'exploitation; si la machine a démarré à un point où elle a commencé à avoir une certaine activité réseau, alors elle a rassemblé suffisamment de hasard physique pour fournir un hasard de qualité suffisamment élevée pour tous les usages pratiques (je parle ici de Linux; sur FreeBSD, cet instant momentané de légère la faiblesse ne se produit pas du tout). D'autre part, /dev/random a tendance à se bloquer à des moments inopportuns, ce qui entraîne des problèmes d'utilisation très réels et gênants. Ou, pour le dire en moins de mots: utilisez /dev/urandom et soyez heureux; utilisation /dev/random et désolé.

( Edit: cette page Web explique les différences entre /dev/random et /dev/urandom très clairement.)

Dans le but de produire un "cookie": un tel cookie doit être tel que deux utilisateurs ne partagent pas le même cookie, et qu'il est impossible pour quiconque de "deviner" la valeur d'un cookie existant. Une séquence d'octets aléatoires le fait bien, à condition qu'elle utilise un caractère aléatoire de qualité adéquate (/dev/urandom c'est bien) et que c'est assez long. En règle générale, si vous avez moins de 2n utilisateurs ( n = 33 si toute la population de la Terre pourrait utiliser votre système), alors une séquence de n + 128 bits est suffisamment large ; vous n'avez même pas besoin de vérifier une collision avec des valeurs existantes: vous ne la verrez pas de votre vivant. 161 bits tient dans 21 octets.

Il y a sont quelques astuces qui sont réalisables si vous voulez des cookies plus courts et que vous souhaitez toujours éviter de rechercher des collisions dans votre base de données. Mais cela ne devrait guère être nécessaire pour un cookie (je suppose un contexte Web). N'oubliez pas non plus de garder vos cookies confidentiels (c'est-à-dire d'utiliser HTTPS et de définir les cookies "sécurisé" et "HttpOnly").

222
Thomas Pornin

Oui, c'est un excellent moyen.

@ L'explication de Thomas le cloue. Et il a tout à fait raison de critiquer le /dev/urandom page de manuel. Repérez.

Mais ignorez "vérifier s'il existe déjà". Ce contrôle est inutile. Ça ne va pas arriver. (Les chances que cela se produise sont inférieures à la probabilité d'être frappé par la foudre - plusieurs fois - le même jour.)

25
D.W.

Soyez conscient des cas Edge si vous utilisez Linux ou NetBSD.

Sous Linux, vous voudrez vous assurer que suffisamment d'entropie a été obtenue après le démarrage pour amorcer correctement le CSPRNG, ou utiliser l'appel système getrandom() pour lire à partir de /dev/urandom et ne bloquer que dans les rares cas où une entropie initiale suffisante après le démarrage n'est pas disponible.

Dans NetBSD, vous souhaitez lire à partir de /dev/random au moins une fois avant de lire dans /dev/urandom pour vous assurer qu'il a été correctement ensemencé.

Sur FreeBSD et MacOS, il n'y a pas de différence entre /dev/random et /dev/urandom.

La réponse courte est toujours d'utiliser /dev/urandom.

Voir Quand utiliser/dev/random vs/dev/urandom pour plus de détails.

1
Tom Hale