简体   繁体   中英

Generating random sequences of bits

I'm trying to generate a file containing absolutely random keys with a given length, Lets say 100bits and store them in a file. What's the best way to do it and which language offers the best libraries? Thanks in advance.

Randomness comes in different levels of "strength"; you can get either truly random bits, or pseudo random bits. The truly random bits derive their entropy from real-world sources. The pseudo random bits produce a sequence of bits that appears random but is in fact predictable.

You should always use a randomness generator designated as having cryptography strength when generating keys. These random bit generators are carefully designed to be truly unpredictable. Never use weaker sources of randomness for generating keys.

In C# you can do so by creating an instance of the aptly named random number generator cryptographic service provider and then call GetBytes to obtain an array of random bytes of the desired length.

Needless to say: be very careful when generating your own crypto keys. Cryptography is all about leveraging the security of the key into the security of the message; if you are not very careful about how you generate, store and transmit keys, then the security system is compromised. Consider hiring an expert on cryptography if you are not one yourself rather than trying to roll your own crypto code.

I note also that depending on your application, 100 bits may be far too small a key size, or far too large. It may be too small in that your algorithm may be vulnerable to attack at a key size that small, and it may be too large in the sense that some countries restrict the usage or export of crypto software that has too high a bit count. Consider consulting a lawyer.

Depends on what you mean by absolutely random. If pseudo random number generators are acceptable then the C++ <random> library is a great option.

If you need stronger guarantees than that then you may still be able to use std::random_device from <random> which offers non-deterministic random numbers if your platform has that capability. It may even offer access to a cryptographic random number generator. You'll have to check your platform's documentation.

#include <random>
#include <iostream>

int main() {
    std::random_device r("/dev/random"); // Cryptographically secure RNG on Linux, OpenBSD, OSX, (using libc++)
    unsigned int completely_random_value = r();
    std::cout << completely_random_value << '\n';
}

One thing that may be relevant to you is this note from Microsoft's documentation about their implementation of random_device in VS11: "In this implementation the values produced by default are not non-deterministic." It's another unfortunate quality of implementation issue with Visual Studio's C++11 library (to go along with, at least, the low resolution of their chrono::high_resolution_clock)

True random numbers cannot be generated by deterministic processes, so the choice of language is in some sense unimportant. Since you say "keys", you are probably looking for cryptographic keys, and generating these by deterministic processes is very dangerous indeed, and the cause of numerous system breaks.

I would rethink the entire thing -- and if you're generating cryptographic keys on your own, you absolutely should rethink the whole thing. Amateurs, no matter how skilled at programming, should not write cryptographic code. That's caused more system bugs than I can count.

It's relatively easy in C/C++, assuming that you understand that there are no such things as random numbers, but merely pseudo-random numbers:

uint8_t *randomBytes(int length)
{
    uint8_t buffer = malloc(length);

    for (int i = 0; i < length; i++)
    {
        buffer[i] = arc4random_uniform(256); // or similar random function
    }

    return buffer; // don't forget to free buffer when done!
}

In Java, you would return a byte array, like this:

byte[] randomBytes(int length)
{
    Random rand = new Random();
    byte[] buffer = new byte[length];

    for (int i = 0; i < length; i++)
    { 
        buffer[i] = (byte) rand.nextInt(256);
    }

    return buffer;
}

In C#, it's mostly the same as Java, but with a few differences:

byte[] randomBytes(int length)
{
    Random rand = new Random();
    byte[] buffer = new byte[length];

    for (int i = 0; i < length; i++)
    { 
        buffer[i] = (byte) rand.Next(256);
    }

    return buffer;
}

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