4

What is the (best) way to create a secure random numbers in Linux (C/ C++ code), more random than the general rand() results, and not pseudo as OpenSSL BN_rand?

In Windows I found CryptGenRandom() as a good option. Is there any equivalent in Linux?

Thank you in advance.

rkellerm
  • 5,362
  • 8
  • 58
  • 95
  • possible duplicate of [True random number generator ](http://stackoverflow.com/questions/37702/true-random-number-generator) – David Titarenco Oct 31 '10 at 08:40
  • 2
    @David Titarenco - I don't think this is a duplicate. My question is about concrete and code to do so, not theory (Although the question is indeed a good reference - thanks for that) – rkellerm Oct 31 '10 at 08:57
  • [More information](http://tinyurl.com/meta-xy) on the problem you're solving would help; it's likely you don't need "truly" random numbers. –  Oct 31 '10 at 09:00
  • They are still mostly pseudorandom. They just use some real entropy sources, but the number of generated bits usually exceeds the entropy bits. – CodesInChaos Oct 31 '10 at 09:22
  • There is no way to generate random numbers in Linux or any other OS. `CryptGenRandom` on Windows doesn't generate true random data either. – jalf Oct 31 '10 at 15:18

7 Answers7

17

you can read from /dev/random which is populated with an entropy pool. There is some good info on the wikipedia site on it: http://en.wikipedia.org/wiki//dev/random

Martijn
  • 11,964
  • 12
  • 50
  • 96
5

"Random" numbers generated by a computer without any external data are pseudo-random. It means that they are generated with a mathematical formula. These algorithms are reliable and should be okay for almost all purposes.

To have a "true" random number, you need an intervention from outside. There are some solutions implemented in various programs (I remember of several ones that used mouse movements or atmospheric noise).

As Martijin just pointed, there is also /dev/random on Linux and OSX. It uses the noise collected by the device drivers.

There is also a web service that I just found : http://www.random.org/clients/http/

Marc Demierre
  • 1,088
  • 13
  • 24
  • You can collect random data on a computer, or use random data from elsewhere (there are several websites which make it available for download; just an example, not saying that is good for security ;). While the rest of your answer is good, your "by definition" isn't. –  Oct 31 '10 at 08:57
  • Yes you're right, the random elements coming from outside are a base for the computer and it generates numbers with it. I'll edit. – Marc Demierre Oct 31 '10 at 09:16
  • Sometimes the "computer" already has some "external" sources of entropy. For instance, it may contains several clocks (CPU clock + Sound card/GPU clock), which don't exactly coincide. – valdo Oct 31 '10 at 10:51
2

1st CryptGenRandom is not "truly" random device by they are enough random to be cryptographically safe.

Similar under Linux (and most unixes) is reading from /dev/urandom.

If you want to get real random numbers you may read /dev/random but you may get blocked waiting for system to collect them if entropy pool is too small.

Artyom
  • 31,019
  • 21
  • 127
  • 215
1

Take a look at boost::random_device.

Edit: It resides in namespace boost::random starting from Boost 1.47 : boost::random::random_device

usta
  • 6,699
  • 3
  • 22
  • 39
  • 1
    C++ offers std::random_device with C++11. It doesn't necessarily use /dev/urandom or an otherwise cryptographic RNG, so you'll have to check your implementation. – bames53 Nov 09 '12 at 21:57
0

You can use quantum random number generators such as Quantis: http://www.idquantique.com/true-random-number-generator/products-overview.html

It utilizes the quantum mechanical probability of a single photon passing or being reflected from a semi transparent mirror and generated random bits up to 4Mbit/s true random bits.

Rubi Sharmax
  • 376
  • 1
  • 3
  • 14
0

/dev/urandom generates some random numbers based on the actions you perform(moving of the mouse,typing,etc!)

0

I wrote this earlier today. Compiles in both C and C++ using GNU compiler on Linux.

#include "rands.h"
#include <sys/types.h> /* for open(2) */
#include <sys/stat.h> /* for open(2) */
#include <fcntl.h> /* for open(2) */
#include <unistd.h> /* for read(2), close(2) */

#define DEVURANDOM "/dev/urandom"

typedef uint8_t TYPE;

TYPE getRandU8()
{
    TYPE rnum = 0;
    int fd = open(DEVURANDOM, O_RDONLY);
    if (fd != -1)
    {
        (void) read(fd, (void *)&rnum, sizeof(TYPE));
        (void) close(fd);
    }
    return rnum;
}

You can change the TYPE to int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, and int64_t as needed (and change the name of the function appropriately). You could also use (signed/unsigned) char, short, int, long, long long, etc. The rands.h file (in the same directory) just has function prototypes for linkage.

pr1268
  • 1,176
  • 3
  • 9
  • 16
  • 1
    I wish to add some comments about my own code: 1. This code is somewhat inefficient as it opens a character special file (/dev/urandom), reads from it, and closes it all within the function. If a program were to call this multiple times, then this could get quite expensive. A way to fix this would be to open the /dev/urandom file elsewhere in the program ONCE, pass the file descriptor to this function and read from it, and close the file at termination of the program. – pr1268 Nov 20 '10 at 13:24
  • 1
    2. I used the low-level read() (from the integer file descriptor) INSTEAD of the higher-level fread() (from a FILE *) because as I've discovered, fread() reads a whole bunch of bytes into a buffer (and then gives your program how much it asks for) whereas read() will only read the number of bytes you specify. With /dev/random and /dev/urandom, using fread() will drain the entropy pool a whole lot faster than read(). – pr1268 Nov 20 '10 at 13:30