Question

Yesterday I asked Are GUIDs generated on Windows 2003 safe to use as session IDs? and the answer combined with combined with this article GUIDs are globally unique, but substrings of GUIDs aren't prompted me to think about replacing my current mechanism of using GUIDs as session ID's in cookies.

Because it's a bit of work to make that change I decided to run a quick GUID test on my Vista PC to see if a sequence of GUIDs was obviously deterministic (what I'm worried about is if an attacker was able to get a sequence of GUIDs generated by my server they would be able to generate new matching ones).

In Raymond Chen's article (which references this very old spec UUIDs and GUIDs from 1998) the GUID is made up of:

  • 60 bits of timestamp,
  • 48 bits of computer identifier,
  • 14 bits of uniquifier, and
  • six bits are fixed

Going by that if I generate 10 GUIDs the first 15 ASCII chars (excluding '-') are the timestamp, the next 12 ASCII chars are the computer identifier, the next 3.5 ASCII characters are random and the last 1.5 characters are fixed.

Getting 10 GUIDs on my Vista PC using the .Net System.Guid.NewGuid() yields:

b4e95ead-3619-4dc2-9102-cf7ab0efd927
a45ee719-decd-46b2-8355-7becbe406f74
9af68d75-35a0-4907-b6ab-f15e33acfe96
bed88fa3-3209-4a19-97dd-85d5428ea5f4
123cb39b-8d81-41c6-8894-f1257a8f7606
e2b1f6b1-5791-4a18-80a9-5dc668574ecb
c52aa660-2629-4659-bb83-5583081e5a1c
76eda32d-ceda-412e-8ade-30c47416e954
cbc4d45e-7281-40d2-9f90-00539b04fe98
be36524c-267c-4791-bc9e-3c20b29d7615

The only discernible pattern from a quick visual inspection is that the 13th ASCII character is always 4.

I'm again left wondering if relying on System.Guid to generate pseudo random session IDs is strong enough to protect a web application where cracking a session ID would be worth at most thousands of dollars?

Update: Instead of using a GUID I now plan to generate my session ID's using the approach below. I'm converting the 384 bit random number to a 0x00 byte string so that it's suitable for use in an HTTP cookie.

RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
byte[] myKey = new byte[48];
rngProvider.GetBytes(myKey);
string sessionID = null;
myKey.ToList().ForEach(b => sessionID += b.ToString("x2"));
Console.WriteLine(sessionID);
Was it helpful?

Solution

It's not a complete answer, but I can tell you that the 13th hex digit is always 4 because it denotes the version of the algorithm used to generate the GUID (id est, v4); also, and I quote Wikipedia:

Cryptanalysis of the WinAPI GUID generator shows that, since the sequence of V4 GUIDs is pseudo-random, given the initial state one can predict up to the next 250 000 GUIDs returned by the function UuidCreate. This is why GUIDs should not be used in cryptography, e.g., as random keys.

The rest of the article, and its references: http://en.wikipedia.org/wiki/Guid

--Edit--

From a security standpoint, I'd suggest that you generate your session ID however you feel like, then cryptographically sign it; that way you can pack in whatever information you want and then just slap a signature on the end - the possible issue being the tradeoff between the size/strength of your key and the resulting size of the cookie. GUIDs are useful as IDs, but I'd only rely on a dedicated cryptographic technique for security.

OTHER TIPS

I suggest you use the System.Security.Cryptography.RandomNumberGenerator. This is designed to produce numbers which can't be reverse engineered. Guid's motivation is to be unique. You could combine both the GUID and secure random number, but a 128 bit secure random number is never going to have a collision on practice.

Some notes:

  1. I doubt that any implementation of GUIDs was designed to be cryptograhpically secure. (And this supposition would be borne out by the article linked for the next item.)
  2. The 13th ASCII character is a signifier of what algorithm was used to generate the GUID.

If you're really concerned with having strong session IDs, then perhaps a cryptographically secure hash of something that cannot be determined from off-machine would be your best approach. Perhaps generating a one-time pad from some internal document or data source would even work.

What are you trying to do? Do you want just a source of random numbers?

Check out random.org and hotbits. Many many years ago, I had a Java library that would gather numbers from these sources, and join them together, to get a quite beautiful random series (though it assumes the two sites aren't in cahootz).

The short answer is, no guid's aren't sufficiently strong to generate session id's if you want to prevent session id guessing and cracking.

For the same reason why you wouldn't want to use a GUID as an AES key, you don't want to use them for any type of sensitive identifies.

A GUID works extremely well for what they are designed to be: A mathematically guarenteed unique ID to never repeat.

Even if cracking a session ID is only worth $1000, imagine if thats done 100 times. Now you're talking serious bling.

I know it's an easy way out to use GUID's but resist, and deal with the pain by taking the proper precautions to adequately secure your application. Your users will thank you.

It is almost impossible to get a duplicate guid considering the possiblities of getting one. Here are some quick math facts

Grains of sand in the world 75,000,000,000,000,000,000

Number of GUIDs 340,282,366,920,938,463,463,374,607,431,770,000,000

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top