Пул энтропии - это накопитель непредсказуемости внутри операционной системы, из которого криптографические генераторы черпают случайность для ключей, сессий и одноразовых значений. Когда старая программа вроде PuTTYgen или GnuPG просит пользователя поводить мышкой по экрану, это не театр и не ритуал: программа буквально собирает физический шум, потому что компьютер сам по себе случайность производить не умеет. Каждая его инструкция детерминирована, каждый такт процессора предсказуем, а криптография держится на противоположном свойстве - на невозможности угадать следующие биты.

Детерминированная машина не умеет в случайность

Компьютер - это машина, которая по одному и тому же входу всегда выдаёт один и тот же выход. Это её достоинство во всём, кроме криптографии. Алгоритм генерации ключа, выполненный дважды в идентичных условиях, породит идентичный ключ, и злоумышленнику останется лишь воспроизвести условия. Поэтому любой криптографически стойкий генератор случайных чисел устроен как двухслойная конструкция. Внутри работает быстрый детерминированный автомат - поточный шифр или хеш-конструкция, который растягивает небольшой секретный ключ в неограниченный поток байтов, неотличимый от шума для любого, кто ключа не знает. Но этому автомату нужен стартовый материал, сид, который нельзя вычислить ни из какого другого состояния системы. Сид должен прийти извне, из мира физики, а не из мира логики. Роль пула энтропии именно в этом: собрать крупицы физической непредсказуемости, аккумулировать их, перемешать и выдать сид, который не воспроизведёт ни один наблюдатель, даже полностью контролирующий софт.

Разница между случайностью и предсказуемостью здесь абсолютна. Ключ длиной 256 бит, выбранный из полного пространства, перебрать невозможно физически. Тот же ключ, выросший из предсказуемого состояния - времени запуска с точностью до секунды и номера процесса - уменьшает пространство поиска до нескольких миллионов вариантов, которые ноутбук перебирает за минуты. Именно поэтому качество пула энтропии - это не инженерная мелочь, а фундамент, на котором стоит вся остальная криптография системы.

Откуда операционная система берёт шум

Источники энтропии в ОС - это коллекция физических мелочей, которые наблюдатель не в силах предсказать с достаточной точностью. Классический набор Linux выглядит так. Тайминги прерываний: моменты прихода сетевых пакетов и срабатывания оборудования дрожат на уровне микросекунд из-за физических процессов в каналах и контроллерах. Джиттер кварцевых генераторов: два кварца на плате никогда не работают ровно на одной частоте, разность их дрейфа тепловая и хаотичная, и современные ядра умеют измерять это рассогласование напрямую, без внешних устройств. Движения мыши и интервалы между нажатиями клавиш: человеческая моторика неповторима, координаты курсора и тайминги нажатий дают по нескольку бит непредсказуемости на событие - отсюда и просьба подвигать мышкой, самый наглядный способ вручную подкормить пул. Дисковые задержки: время позиционирования головок и отзывчивость контроллера зависят от механики, вибраций и температуры.

Отдельная строка - аппаратные генераторы в процессорах. Intel добавила инструкцию RDRAND, которая выдаёт случайные числа из встроенного источника термического шума, отбелённого и прогнанного через кондиционер на кристалле, а RDSEED даёт сырой материал для посева генераторов. Это удобно и быстро, особенно на бездисковых серверах, но вызвало долгие споры о доверии: внутренности чипа не проверить, аудиту конструкция не поддаётся, а требование целый ряд государств к встраиванию закладок в оборудование никто не отменял. Практический консенсус криптоинженеров прост: RDRAND используют, но не в одиночку - его выход подмешивают в общий пул вместе с остальными источниками, так что компрометация любого одного канала не раскрывает результат. Энтропия от множества независимых источников складывается, а не усредняется.

Как пул перемешивается и почему urandom победил

Внутри пула накопленный шум не хранится сырым: он непрерывно перемешивается криптографической функцией. Исторически ядро Linux применяло SHA-1 - каждая порция событий подавалась в хеш вместе с текущим состоянием пула, и извлечение случайных байтов тоже шло через хеширование, так что внутреннее состояние никогда не покидало ядро в открытом виде. Современные версии перешли на ChaCha20: пул фактически стал поточным шифром, ключ которого постоянно обновляется свежим шумом, а выход читается как шифротекст нулей. Односторонность гарантирует, что даже утечка выхода не восстанавливает состояние, а постоянное подмешивание не даёт состоянию застаиваться.

Параллельно ядро ведёт оценку: каждый источник получает консервативную оценку в битах энтропии, и счётчик показывает, сколько настоящей непредсказуемости накоплено. Из этой оценки исторически выросла пара устройств. /dev/random блокировался, когда счётчик падал - честно, но на практике губительно: серверы зависали при генерации ключей, администраторы обходили блокировку костылями и получали худшую криптографию, чем без неё. /dev/urandom не блокируется никогда и выдаёт поток из того же перемешанного состояния. Современная позиция, закреплённая и в ядре Linux после переработки подсистемы: после первичной инициализации пула urandom предпочтителен практически всегда, потому что криптографический генератор, однажды получивший 256 бит настоящей энтропии, остаётся стойким независимо от того, сколько байтов из него вычитали. Блокировка после инициализации защищала от угроз, которых математика конструкции уже не допускает, а реальный риск - ранний вызов до посева - решается системным вызовом getrandom с его корректным ожиданием готовности. В Windows ту же роль играет BCryptGenRandom из криптопровайдера CNG и его предшественник CryptGenRandom, которые обращаются к ядерному источнику через драйвер KSECDD; пула с блокировками и ручной оценкой битов там нет, посев и подмешивание скрыты от приложений целиком.

Катастрофы, когда энтропии не хватило

История криптографических провалов устроена поучительно однобоко: алгоритмы ломают редко, а посевы генераторов - постоянно. Три классических случая стоит знать каждому, кто генерирует ключи.

  1. Debian OpenSSL, 2008 год. Сопровождающий пакета закомментировал две строки кода, на которые ругался анализатор Valgrind: обращение к неинициализированной памяти выглядело как ошибка. Одна из строк подмешивала в генератор содержимое процессной памяти как дополнительный источник шума. После правки единственным меняющимся входом остался идентификатор процесса - около 32 тысяч вариантов. Все ключи SSH и SSL, созданные на Debian и производных в течение двух лет, оказались из крошечного предсказуемого множества; инструменты перебора этого пространства ходят по сети до сих пор, а чёрные списки слабых ключей вошли в дистрибутивы.
  2. Встраиваемые устройства при первой загрузке. Маршрутизаторы, камеры, сертификаты-на-чипе загружаются в идеально воспроизводимом состоянии: нет часов реального времени с батарейкой, нет диска, сеть ещё не поднята, загрузка идёт по одной и той же временной диаграмме. Генерация ключа на первой загрузке в таких условиях давала одинаковые ключи у тысяч устройств. Массовые сканирования интернета находили сертификаты с общими простыми делителями и дублирующиеся RSA-ключи именно по этой причине.
  3. Клонированные виртуальные машины. Снапшот виртуалки замораживает состояние генератора вместе со всей памятью. Десяток клонов одного образа продолжают выдавать идентичные «случайные» потоки: одинаковые сессионные ключи, одинаковые одноразовые значения, предсказуемые идентификаторы. Лечение штатное - virtio-rng и аналоги, которые пробрасывают энтропию с гипервизора в гостевую систему, плюс пересев генератора при каждой загрузке клона.

Сколько энтропии достаточно и почему кубики проигрывают генератору

Порог современной криптографии прост: 256 бит настоящей энтропии на сид - с двойным и тройным запасом против любых ослаблений. Перебор 2 в 256-й степени вариантов недостижим для любой мыслимой вычислительной техники, включая гипотетические квантовые машины после квадратичного ускорения Гровера. Больше бит в посеве не добавляет стойкости - добавляет лишь уверенность в оценке. Практический вывод для инженера: проблема никогда не в количестве битов, а в честности их происхождения.

Отсюда понятно, почему ручные методы хуже системного пула. Плакаты и сервисы, предлагающие сгенерировать ключ бросками кубиков с записью результата на листе, звучат привлекательно благодаря физике процесса, но проигрывают по всей линии. Человек бросает кубики медленно, устаёт, сбитывается, записывает с ошибками; телесное утомление даёт корреляции, которые трудно заметить глазом; лист с цифрами потом нужно ввести в компьютер без опечаток и без утечки. ## Куда смотрит практика эксплуатации пула

В реальной системотехнике вопрос «сколько энтропии» быстро сменяется вопросом «откуда мне знать, что она есть». Современные дистрибутивы и Windows решают это через ранний посев: при первой загрузке сохранённый на диске файл seed подмешивается в пул и обновляется заново до того, как какой-либо демон попросит случайности. Виртуальные машины клонируют ту же проблему сильнее: две копии одной ВМ встают с идентичным состоянием генератора, поэтому у гипервизоров есть канал virtio-rng, по которому хост подкидывает свежий шум гостю каждую загрузку. Сервера со встроенными криптопроцессорами, наоборот, собирают энтропию аппаратным тремя способами и по внутреннему самотесту отклоняют повторные посевы.

Отдельная страница истории - оценка качества. Проверить «случайность» напрямую невозможно: случайная последовательность может выглядеть закономерной чисто по воле статистики. Поэтому индустрия идёт по окружному пути - вместо оценки выхода оцениваются источники: модель шума кварцевого джиттера, модель микрофона таймингов, аппаратные петли с инверсным усилением затвора и так далее. На выходе инженер опирается не на осмотр выборок, а на гарантию, что физический процесс, лежащий внутри генератора, имеет известную минимальную непредсказуемость на единицу времени. Работает и стратегия смешивания: если источники независимы и хотя бы один честен, смесь хэшем не умаляет качество лучшего из них - поэтому зашёл в пул аппаратный генератор процессора, вы ничего не теряете, добавив к нему шум периферии.

Человеческий запрос «подвигайте мышой» - это экономическое наследие эпохи, когда у процессоров не было RDRAND, у дисков не было полезного дрожания, а аппаратные генераторы стоили дорого. Экранная активность пользователя вкидывала в пул десятки событий с микросекундными отклонениями, по правилам простиравшихся источником номер один. Сегодня тот же запрос выглядит кокетством интерфейса, но подводная часть осталась подлинной: между детерминированной машиной и стойким ключом лежит единственный ингредиент в виде физической непредсказуемости, и инженер, который знает, откуда она берётся у его системы, спит спокойнее.

Системный генератор собирает шум непрерывно от дюжины независимых источников, перемешивает его проверенной конструкцией, оценивает запас битов консервативно и никогда не устаёт. Просьба подвигать мышкой у старых программ - не отказ от этой машинерии, а её ручной запуск в момент, когда автоматических источников ещё мало: на свежей системе, в урезанном окружении, на первой загрузке. Мышь нужна генератору ровно на тех несколько секунд, пока аппаратура не набрала шума сама, - после чего пул энтропии живёт самостоятельно, тихо перемешивая физику мира в непредсказуемость, на которой стоит вся защита ключей.