At the company I work at, we use the output of the Guid.NewGuid method as a session id. So when a customer logs into our website, the output of Guid.NewGuid becomes the customer's session id and is used to authenticate all subsequent requests (until the expiry date). https://docs.microsoft.com/en-us/dotnet/api/system.guid?view=net-5.0

I am creating an an API that uses sessions, and naturally I decided to use the same method as our website to generate the session ids, but I am not sure if it's secure. I have seen some (non authoritative) posts on the internet saying that Guid.NewGuid is not random enough, but I haven't been able to find anything authoritative.

Does anyone know if the Guid.NewGuid method is random enough for a session id? I guess I could just use the RNGCryptoServiceProvider of .NET to do it, but I'd rather do it in the same way as our website, assuming it's secure to do so.


GUIDs in general are intended to be unique but not necessarily unpredictable, which generally makes them unsuitable for session tokens.

However, there are multiple defined types of GUID, and the type of a GUID is marked by the first digit (four most significant bits) of the third part (7th byte) of the structure. At least on Windows, Guid.NewGuid() invokes CoCreateGuid, which invokes UuidCreate, which on modern Windows versions (dating back to at least Windows 2000) creates a type 4 GUID. Type 4 GUIDs are created using a cryptographically secure random number generator (for the Windows APIs, almost certainly CryptGenRandom). Thus, Guid.NewGuid() returns almost 128 bits of cryptographically secure entropy (GUIDs are 128 bits, but some bits are not random, to indicate the type). That's sufficient for almost any practical website's security token.

However, I can't find anything in the current docs that guarantees the API will return a type 4 (or any other similarly-unpredictable type) GUID. I think there may have been at one point, but none of the APIs I looked at above specified this, aside from UuidCreate specifying that it does not reveal the machine's MAC address (which rules out one specific older type). As such, I would say that you should not rely on Guid.NewGuid() to return a secure random value, because even if it currently does so on all platforms, the API doesn't promise this and an update could change that behavior at any time.

Invoking a secure (P)RNG directly, for at least 128 bits of entropy, and then either base64- or HEX-encoding it (with or without the dashes that are usually displayed in GUIDs), is probably a better plan. According to https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator?view=net-5.0, you should call System.Security.Cryptography.RandomNumberGenerator.Create() rather than directly invoking RNGCryptoServiceProvider (which may not be available on some platforms) to get your secure RNG object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.