[HowTo] Generate secure random numbers on Linux

Hi all ! In this new post I will explain how to generate secure random number on *nix system. In many case, often in cryptographic system, the application needs to have sources of random number. The lack of randomness can be hard to diagnose. For example, I’m sure you have heard of the Debian random number generator failure in OpenSSL. This bug went unnoticed for 2 years, compromising a vast number of keys. Actually, a lot of pseudorandom number generator (PRNG) are not secure.

If you want to develop cryptographic applications, you must NOT do this :

  • Rely only on predictable entropy source (timestamp, sensor, PID, disk space etc.)
  • Rely only on “general PRNG” functions like rand(), srand(), random()
  • Use “comic stuff” like http://www.random.org (random data may be shared with other parties…)
  • Design your own PRNG (developer, cryptographer, mathematician are different professions)
  • Reuse the same randomness across applications
  • Use directly the entropy as pseudorandom data

This list is not complete but it regroups the most important things to avoid in all circumstances. On *nix system, a good randomness is /dev/random and for your information, on the Intel CPU (Ivy bridge based) the built-in PRNG guarantees high entropy.

On *nix system, you should use /dev/random or /dev/urandom. “The first one is better because it doesn’t return data if the entropy is insufficient” (to be clarified. it’s not exactly right). Of course you must be aware that this blocking feature limits the usability and it’s for this reason that /dev/urandom is more often used.

Here a small C code which performs this extraction.

/*
 * getRandom.c
 *
 *  Simple example which show how to extract random data
 *  of a specified size (in bytes) in a Unix OS.
 *
 *  @author cyrill gremaud - gremaudc@gmail.com
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define KEY_SIZE 32

/* Read sizeByte in Unix randomness source and put them into output */
void generateRandom(unsigned char* output, int sizeBytes)
{
    int fd;
    int bytes_read;

    /** Best randomness source on Unix system. Do not works on Windows. */
    if((fd = open("/dev/urandom", O_RDONLY)) == -1)
        perror("Error: impossible to read randomness source\n");

    bytes_read = read(fd, output, sizeBytes);
    if (bytes_read != sizeBytes)
        fprintf(stderr, "read() failed (%d bytes read)\n", bytes_read);

    close(fd); //thanks Bennet Yee
}

int main()
{
    unsigned char key[KEY_SIZE];

    int i, j;
    for(i = 0; i < 10; i++)
    {
        generateRandom(key, (int)sizeof(key));
        printf("Key %d = ", i);

        for(j = 0; j < KEY_SIZE; j++)
            printf("%x", key[j]);

        printf("\n");
    }

    return 0;
}

This small code call 10 times the function generateRandom() and print each time the generated data. Important to know that the KEY_SIZE represents the size in bytes but in cryptography, the size of the “keys” are often expressed in bits. In this case the generated keys are 256 bits length.

I hope this code will be useful for you. I recommend the next website to get the best practices in cryptography development.

Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.