简体   繁体   中英

Generate random 128 bit number

I'm working on a school assignement, and one of the requirements is to generate a random 128-bit number. I'm wondering how to do this in C#, could this method work?

byte[] RND128NUMBYTE = new byte[128];
Random Rand = new Random();
Rand.NextBytes(RND128NUMBYTE);

Thank you all in advance

EDIT: First of all, thank you all for your answers. Anyway it's better if I clearify the assignement: I'm building a server/client application in a secure way. After the user connects to the server, to communicate with the other user connected to that server it must be authenticated.User ask auth to the server and the server answer the client with a 128-bit random number. After that some other process will be done.

The size of an array is given in elements. So for a byte array you need 16 elements with 8 bits each, and not 128 elements.

You can either use System.Random.NextBytes or RNGCryptoServiceProvider.GetBytes .

But System.Random.NextBytes is probably not a good choice, since the bad seeding of System.Random means you don't get the properties expected of a random 128 bit number. For example you will most likely get collisions even if you generate less than 2^64 numbers. A 128 bit number from a good PRNG is as globally unique as a GUID, one drawn from System.Random certainly isn't.

byte[] bytes = new byte[16];
using(var rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(bytes);
}

First off, you are generating 128 random bytes, not random bits. But your clarification makes all the difference:

I'm building a server/client application in a secure way. After the user connects to the server, to communicate with the other user connected to that server it must be authenticated.User ask auth to the server and the server answer the client with a 128-bit random number.

In that case your solution is deeply, deeply wrong even after you take into account the fact that you're generating eight times too many bits. System.Random is only pseudo-random , and in fact has only 31 bits of entropy when seeded as you are doing . (*) In order to be secure you need all 128 bits of entropy.

Remember, every missing bit makes the problem half again as easy to attack; if you need 128 bits of entropy and you have 31, then the problem isn't four times easier to attack. The problem is 2 128-31 = 10 29 times easier to attack!

Coincidentally I just wrote a blog article about this. I challenged readers to figure out the rest of a deck of cards that I had shuffled with Random when given only the first five or six cards. Someone found a solution by brute force in a couple of hours. Random is extremely weak. . See http://ericlippert.com/2013/05/06/producing-permutations-part-seven/

If you need crypto strength randomness for a security system then you need to use a special purpose randomness source that has more than 128 bits of entropy in it.

Therefore CodeInChaos's answer is the correct one.

There are two morals of this story:

First, this is why designing security systems is so hard. There are so many details to get right, and you have to get all of them right, or the system is not secure.

Second, make sure you give enough information in the question to get a good answer.


(*) In fact it has considerably less than that, since some of those 2 31 possible seeds are far more likely than others.

Isn't figuring that out what the assignment is about?

Do like this:
Implement your theory. Run it many many times and store the results. Do some statistics on it like checking for lowest and highest value to know you are inside limits. For extra plus count each result and make sure they are evenly spread.

the requirements is to generate a random 128-bit number

I think that assignment is a bit too harsh, I hope they mean a pseudo-random number . I would like to point out you'll have to break problems up into parts you understand.

You've correctly initialized a PRNG and know how to let it fill a byte array :

Random Rand = new Random();
Rand.NextBytes(RND128NUMBYTE);

Now you need to fill a space of 128 bits with randomness. What is 128 bits, does .NET or C# provide you with access to bits? Not directly, but you have a byte type. This type utilizes 8 bits, so you'll only need 128 / 8 = 16 bytes.

You were almost there, you just have to create an array of 16 bytes instead of 128:

byte[] RND128NUMBYTE = new byte[16];

How to convert these bytes into a "number" I'll let up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM