Il y a un moment, j'ai travaillé sur une application web où les utilisateurs peuvent acheter des billets. En raison de la façon dont notre client, processus travaillé, ce que vous avez effectivement obtenu à la suite de votre achat a été une URL avec le numéro de ticket en elle.
Ces billets à acheter une propriété dans le Moyen-Orient, et chaque billet était potentiellement une valeur d'environ de 3 000 000$. Clairement distribue séquentielle entiers aurait été une mauvaise idée. Nous avons utilisé Guid comme ils sont fondamentalement impossible à deviner, mais ma question est: sont-ils suffisamment sécurisé?
Si je comprends bien, le Guid .NET produit sont totalement pseudo-aléatoire (à l'exception de quelques non variable de bits). Cependant, je ne sais pas quel algorithme est utilisé pour les générer.
La documentation MSDN nous dit qu' Random
est rapide et l'insécurité, et RNGCryptoServiceProvider
est lent et sûr. C'est, il est raisonnable de supposer que quelqu'un pourrait mettre dans l'effort, de prédire le résultat d' Random
, mais pas de RNGCryptoServiceProvider
.
Si vous avez vu une assez longue séquence de Guid, serait-il possible de prédire les futures sont-elles? Si oui, combien auriez-vous besoin de voir?
[Dans notre cas particulier, il y avait la sécurité physique des vérifications plus tard, il fallait présenter le passeport que vous avez utilisé pour acheter votre ticket de sorte qu'il n'aurait pas été trop mauvais si quelqu'un l'avait deviné de quelqu'un d'autre GUID, nous n'avons donc pas de sueur, à l'époque. La commodité d'utiliser le GUID comme une clé de base de données fait une utile type de données à utiliser.]
Edit:
Si la réponse est "pas assez".
À l'aide de 0xA3's réponse ci-dessous, et suivre les liens à partir de la question qu'il a lié pour, le code suivant génère un niveau de chiffrement aléatoire GUID valide par la Section 4.4 de la norme RFC 4122:
static Guid MakeCryptoGuid()
{
// Get 16 cryptographically random bytes
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] data = new byte[16];
rng.GetBytes(data);
// Mark it as a version 4 GUID
data[7] = (byte)((data[7] | (byte)0x40) & (byte)0x4f);
data[8] = (byte)((data[8] | (byte)0x80) & (byte)0xbf);
return new Guid(data);
}
Ce produit Guid beaucoup plus lentement que d' Guid.NewGuid()
, mais avec 122 bits de "très aléatoire" des données, ils sont en sécurité imprévisible.
Bien sûr, tout chiffrée de manière aléatoire texte aurait fait pour un numéro de billet, mais les Guid sont assez pratique. :-)
Comme avec d'autres version 4 Guid il n'y a pas de garantie absolue de l'unicité, mais les chances sont impressionnants. Tant que vous avez moins de 326,915,130,069,135,865 (c'est à dire sqrt(-2*2^122*ln(0.99))) Guid en jeu simultanément, vous pouvez être plus de 99% sûr qu'il y a pas de collisions. Mettre une autre manière: si comme le mien, votre application devra erreurs de dépassement de tous sur la place si vous avez plus d' int.MaxValue
de à peu près tout, vous pouvez être plus de 99.9999999999999999% sûr de pas de collisions (e^-(((2^31-1)^2)/(2*2^122))). C'est environ mille fois plus sûr que vous pouvez être qu'une météorite ne pas éliminer la plupart de la vie sur Terre dans la seconde de l'application live (c'est à dire une par de 100 millions d'années).