1

I'm generating an anti-CSRF token with this code:

TokenCSRF = new Random(Guid.NewGuid().GetHashCode()).Next(1, 9999).ToString();

Is this token guessable or truly random as expected?

Edit: I replaced the token generator with this:

    byte[] byt = new byte[sizeof(Int32)];
    RNGCryptoServiceProvider rngCrypto = new RNGCryptoServiceProvider();

    rngCrypto.GetBytes(byt);

    return BitConverter.ToInt32(byt, 0);
halfer
  • 19,824
  • 17
  • 99
  • 186
frenchie
  • 51,731
  • 109
  • 304
  • 510
  • 3
    why not just `Guid.NewGuid()`? – Rahul Jun 28 '16 at 22:22
  • 4
    Who says Guid's are *guaranteed* to be random? Guid's are source of uniqueness not randomness. Use a proper source of randomness for something that should be random. – Mike Zboray Jun 28 '16 at 22:23
  • Because a number between 1 and 10,000 is good enough; could also make it between 1 and 100K or a million. – frenchie Jun 28 '16 at 22:23
  • @mikez: actually, I'm generating a random number, the guid is there to seed the generator. – frenchie Jun 28 '16 at 22:24
  • Possible duplicate of [How do I generate a random int number in C#?](http://stackoverflow.com/questions/2706500/how-do-i-generate-a-random-int-number-in-c) – Heretic Monkey Jun 28 '16 at 22:25
  • This might help as well: http://stackoverflow.com/questions/12240885/generating-a-unique-and-random-url-in-c-sharp – devuxer Jun 28 '16 at 22:48

2 Answers2

9

Is this token guessable or truly random as expected?

That is the wrong question to ask.

Mike z's comment is correct. Guids are guaranteed to be unique, not random. There are different guid generation techniques, and some of them are more random than others. In particular, a guid generator is allowed to generate sequential guids. Most do not, but if you are using a guid for something other than uniqueness, you are using it off-label. I do not like doing anything off-label when security is on the line.

In particular, we have no evidence that any security professional has reviewed the code in either the guid generator or the hash generator to ensure that it has sufficient entropy to defeat an attacker. You should base your security upon tools which have been reviewed by experts.

While we are at it: the code itself is bizarre. It presumes that the hash of a guid has sufficient entropy to seed a random number generator, and then you generate a single 5 decimal digit number from that RNG. By assumption you already have a 32 bit random number in hand; why are you not using it as your random number, if it's already a source of randomness good enough to be a seed? You have a random seed that is more than large enough to be the random number you seek! Feeding it into Random is not going to make it more random.

That said, you should not be using it at all.

The right question to ask is:

What is the correct way to generate a random number for a security purpose?

Use a crypto-strength randomness generator whose on-label use is precisely that. There is one available in the .NET runtime library; use it!

Further reading:

https://blogs.msdn.microsoft.com/ericlippert/tag/guids/

Part 3 is in particular germane to your question.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Ok, I'll into the crypto class. – frenchie Jun 28 '16 at 23:03
  • What if the goal is to generate a number that is both random *and* unique? – devuxer Jun 28 '16 at 23:21
  • @devuxer: Begin by defining "unique" *very* carefully. A type 4 GUID, for example, is *statistically* unique. If we had a computer generating GUIDs randomly then we would expect a collision against a specific guid in, say, 30 trillion years or so. Is that the kind of uniqueness you care about? If we had every computer in the world generating guids and any two could collide then we'd expect a collision in about an hour. Is *that* the kind of uniqueness you care about? – Eric Lippert Jun 28 '16 at 23:32
  • Or do you care about some other metric for uniqueness? Once you have *carefully* defined your metric for uniqueness then we can discuss how to generate numbers that are both unpredictable *and* unique. – Eric Lippert Jun 28 '16 at 23:34
  • For my particular use case, all the numbers would be generated by a single machine, and the degree of statistical uniqueness you describe for a type 4 GUID would be more than adequate. – devuxer Jun 28 '16 at 23:40
1

GUID is guessable because part of it is identified by the machine on which it is generated, and part is the timestamp. It is nothing better than seeding current timestamp instead, which is again guessable.

If you want to generate secure tokens, you may wish to use System.Security.Cryptography.RNGCryptoServiceProvider class, or some similar method.

On a related note, do not limit your tokens to 10K values or anything that small. You would open yourself for brute force attacks. Use something like 64-bit at least and then you will be safe. If you rely on cryptographic RNG, you may wish to generate 8 or 16 bytes, then turn them to string with base-64 encoding. That sounds pretty safe to me.

Zoran Horvat
  • 10,924
  • 3
  • 31
  • 43
  • A guid is *not* guaranteed to be made up of the machine address and the current time; that's a type 1 guid. Guids generated by NewGuid are, in practice, random type 4 guids. But you should not rely on this fact for a security purpose; there is no guarantee that the guid generator has been audited by security professionals to be fit for this purpose. – Eric Lippert Jun 28 '16 at 22:56
  • Actually it's a token that's used for ajax requests and each request issues a new token so that token is only valid for one request. – frenchie Jun 28 '16 at 23:02
  • If attacker can make a sequence of requests, then he can deduce the pattern (if any) and then guess the next one in line. This might not be the case, but as per Mr. Lippert's explanation, GUID doesn't come with any guarantee on randomness. Its primary role is to be unique and all GUID algorithms are dealing with that problem primarily (plus some more, still not related to security...). – Zoran Horvat Jun 28 '16 at 23:06
  • In practice, the type-4 guid generator uses a less-than-crypto-strength random number generator. It's pretty good, but it is not designed to be robust against analysis attacks. – Eric Lippert Jun 28 '16 at 23:35