Книга: Linux программирование в примерах

12.6.3. Особые файлы /dev/random и /dev/urandom

12.6.3. Особые файлы /dev/random и /dev/urandom

Как rand(), так и srandom() являются генераторами псевдослучайных чисел. Их вывод для одного и того же начального значения является воспроизводимой последовательностью чисел. Некоторым приложениям, подобным криптографическим, необходимо, чтобы их случайные числа были действительно (более) случайными. С этой целью ядро Linux, также как различные BSD и коммерческие Unix системы предусматривают специальные файлы устройств, которые предоставляют доступ к «энтропийному пулу» случайных битов, которые ядро собирает от физических устройств и других источников. Из справочной страницы random(4):

/dev/random

[Байты, прочитанные из этого файла, находятся] внутри предполагаемого числа шумовых битов в энтропийном пуле, /dev/random должен подходить для использования в случаях, когда необходим высокий уровень случайности, таких, как одноразовая генерация ключа или блока памяти. Когда энтропийный пул пустой, чтение /dev/random будет блокироваться до тех пор, пока не будет собран дополнительный шум окружения.

/dev/urandom

[Это устройство будет] возвращать столько байтов, сколько затребовано. В результате, если нет достаточной энтропии в энтропийном пуле, возвращаемые значения теоретически уязвимы для криптографической атаки алгоритма, использованного драйвером. Знание того, как это сделать, недоступно в современной не секретной литературе, но теоретически возможно существование подобной атаки. Если для вашего приложения это представляет проблему, вместо этого используйте /dev/random.

Для большинства приложений чтения из /dev/urandom должно быть вполне достаточно. Если вы собираетесь написать криптографические алгоритмы высокого качества, следует сначала почитать о криптографии и случайности; не полагайтесь здесь на поверхностное представление! Вот еще одна наша программа для бросания костей, использующая /dev/urandom:

1  /* ch12-devrandom.с --- генерирует бросание костей, используя /dev/urandom. */
2
3  #include <stdio.h>
4  #include <fcntl.h>
5  #include <stdlib.h>
6
7  char *die_faces[] = { /* Управляет ASCII графика! */
    /* ... как ранее ... */
31 };
32
33 /* myrandom --- возвращает данные из /dev/urandom в виде unsigned long */
34
35 unsigned long myrandom(void)
36 {
37  static int fd = -1;
38  unsigned long data;
39
40  if (fd == -1)
41  fd = open("/dev/urandom", O_RDONLY);
42
43  if (fd == -1 || read(fd, &data, sizeof data) <= 0)
44   return random(); /* отступить */
45
46  return data;
47 }
48
49 /* main --- вывести N различных граней кубиков */
50
51 int main(int argc, char **argv)
52 {
53  int nfaces;
54  int i, j, k;
55
    /* ...проверка args, вычисление nfaces, как ранее... */
68
69  for (i = 1; i <= nfaces; i++) {
70   j = myrandom() % 6; /* обеспечить диапазон 0 <= j <= 5 */
71   printf("+-------+n");
72   for (k = 0; k < 3; k++)
73    printf("|%s|n", die_faces[(j * 3) + k]);
74   printf("+-------+n");
75   putchar('n');
76  }
77
78  return 0;
79 }

Строки 35–47 предоставляют интерфейс вызова функции для /dev/urandom, читая каждый раз данные unsigned long. Издержками является один дескриптор файла, который остается открытым в течение жизни программы.

Оглавление книги


Генерация: 1.300. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз