Как известно, компьютеры не могут генерировать по-настоящему случайные числа. Они используют математическую формулу, производя какие-то действия над изначальным числом. Формула эта — детерминированная, т.е. если взять одно и то же изначальное число дважды, то на выходе будет то же самое. Обычно полученное таким образом псевдослучайное число скармливается назад в формулу, целиком или как часть изначального числа.
Например, вот такая формула (сишный синтаксис): x = (x * 17) % 11
Начиная с x = любое натуральное число, она будет выдавать псевдослучайные натуральные числа от 1 до 10. Но последовательность будет всегда одной и той же — на выходе видим 8, значит, следующим числом будет 4. Конечно, настоящие формулы для генерации псевдослучайных чисел намного более сложны (например, хеширование SHA256) и очень хорошо апроксимируют случайное распределение, но всё равно рано или поздно даже они начинают зацикливаться.
Соответственно, проблема в том, чтобы где-то взять это самое изначальное число, которое будет достаточно случайным, и задача ставится как сбор энтропии (случайных событий).
Например, очень популярен сбор случайности от действий человека. Так, можно считать количество тактов процессора между нажатиями кнопок на клавиатуре. Даже самая дисциплинированная машинистка не сможет повторить их один-в-один. Примерно так и работает сбор энтропии во Фрюниксах — /dev/random считает такты процессора между прерываниями.
У этого подхода тоже есть проблемы. У незанятого сервера, где мало взаимодействий, генерирующих прерывания, проблема сбора энтропии стоит довольно остро. Я даже более скажу — возможна атака, которая будет подсовывать этому серверу какую нужно “случайность”, и на этой основе ломать алгоритм шифрования. Примерно так работал недавний KRACK для беспроводных сетей — где крякер заставлял сеть переиспользовать значение, которое должно быть одноразовым.
Поэтому для особо важных вещей, где криптостойкость является критически важным делом, к сбору энтропии очень серьёзный подход. Мой любимый метод — подключённый к серверу сч0тчик Гейгера и источник радиации. Время между регистрацией двух ионизирующих частиц абсолютно случайно.
Но есть и не такие радикальные способы. Так, компания Cloudflare, занимающаяся предоставлением услуг инфобезопасности, придумала интересную методику с применением лавовых ламп.
Картинка из статьи на ZDNet.
Перемещения расплавленного парафина в масле являются случайными. Cloudflare построили стену с матрицей из 100 лавовых ламп. Эта матрица постоянно фотографируется, и из фотографий вычисляется хеш — который и является источником энтропии. Таким образом достигается прекрасная криптостойкость алгоритмов, которые Cloudflare использует для шифрования траффика между своими распределёнными серверами.
Чорт возьми, изящно!