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?
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").
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.)
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.