Как работает криптографически безопасный генератор случайных чисел?

Я понимаю, как работают стандартные генераторы случайных чисел. Но при работе с crytpography случайные числа действительно должны быть случайными.

Я знаю, что есть инструменты, которые читают космический белый шум чтобы помочь создать безопасные хэши, но ваш стандартный компьютер не имеет этого.

Как криптографически безопасный генератор случайных чисел получить его значения не повторяются?

5 ответов


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

например, /dev / random(4) в Linux собирает информацию об изменении времени аппаратных прерываний из таких источников, как жесткие диски, возвращающие данные, нажатия клавиш и входящие сетевые пакеты. Этот подход безопасен при условии, что ядро не переоценивайте, сколько энтропии она собрала. Несколько лет назад оценки энтропии из различных источников были уменьшены, что сделало их гораздо более консервативными. Вот это объяснение того, как Linux оценивает энтропию.

ни один из вышеперечисленных является особенно высокой пропускной способностью. /dev / random(4), вероятно, безопасен, но он поддерживает эту безопасность, отказываясь выдавать данные, когда он не может быть уверен, что эти данные безопасно случайны. Если вы хотите, например, создать много криптографических ключей и nonces, то вы, вероятно, захотите прибегнуть к аппаратным генераторам случайных чисел.

часто аппаратные RNGs разработаны о выборке из разницы между парой осцилляторов, которые работают с близкой к той же скорости, но чьи скорости слегка варьируются в зависимости от теплового шума. Если я правильно помню, генератор случайных чисел, который используется для лотереи премиальных облигаций Великобритании, Эрни, работает так путь.

альтернативные схемы включают отбор проб шума на CCD (см. lavaRND), радиоактивного распада (см. hotbits) или атмосферный шум (см. random.org, или просто подключите AM-радио, настроенное где-то, кроме станции, к звуковой карте). Или вы можете напрямую попросить пользователя компьютера стучать по клавиатуре, как сумасшедший шимпанзе на минуту, что плывет лодка.

извинения за отсутствие встроенные ссылки, но, по-видимому, я должен записать больше своей жизни на этом сайте, прежде чем мне разрешат публиковать больше.

EDIT: отставить это. Поскольку некоторые люди были достаточно добры к этому мешку с костями, чтобы щелкнуть эту заостренную штуковину слева, мне, по-видимому, разрешено поместить остальные ссылки. Спасибо вам добрые люди! ^_^

EDIT: как отметил Андрас, я только думал поговорить о некоторых из наиболее распространенных схем сбора энтропии. Томас Pornin по ответ и Иоганнес Rössel-х оба делают хорошую работу по объяснению того, как можно калечить собранную энтропию, чтобы снова передать ее кусочки.


для криптографических целей необходимо, чтобы поток был "вычислительно неотличим от равномерно случайных битов". "Вычислительно" означает, что она не должна быть по-настоящему случайной, а должна казаться таковой любому, кто не имеет доступа к компьютеру Бога.

на практике это означает, что система сначала должна собрать последовательность n действительно случайные биты. n должно быть достаточно большим, чтобы помешать исчерпывающему поиску, т. е. невозможно попробовать все 2^n комбинации n бит. Это достигается, в отношении современных технологий, до тех пор, пока n больше, чем 90-или-так, но криптографы просто любовь полномочия двух, поэтому принято использовать n = 128.

эти n случайные биты получаются путем сбора "физических событий", которые должны быть непредсказуемыми, насколько это касается физики. Обычно используется синхронизация: CPU имеет счетчик циклов, который обновляется несколько миллиардов раз в секунду, а некоторые события происходят с неизбежным количеством джиттера (входящие сетевые пакеты, движения мыши, нажатия клавиш...). Система кодирует эти события, а затем "сжимает" их, применяя криптографически безопасную хэш-функцию, такую как SHA-256 (вывод затем усекается, чтобы получить наш n bits). Здесь важно то, что кодировка физических событий имеет достаточно энтропия: грубо говоря, что упомянутые события могли коллективно предполагать по крайней мере 2^n комбинаций. Хэш-функция, по ее определению, должна хорошо концентрировать эту энтропию в n-битовую строку.

Как только у нас есть n биты, мы используем PRNG (генератор псевдослучайных чисел), чтобы вытянуть столько битов, сколько необходимо. PRNG считается криптографически безопасным, если, предполагая, что он работает над достаточно широким неизвестным n-битным ключом, его выход вычислительно неотличим от равномерно случайных битов. В 90-х, популярный выбор алгоритм RC4, который очень прост в реализации и довольно быстро. Однако оказалось, что у него есть измеримые предубеждения, то есть он не был таким неразличимым, как хотелось изначально. The проект eSTREAM состоял в сборе новых конструкций для PRNG (на самом деле потоковые шифры, потому что большинство потоковых шифров состоят из PRNG, выход которого XORed с данными для encrypt), документирование их и продвижение анализа криптографами. Портфель eSTREAM содержит семь проектов PRNG, которые считались достаточно безопасными (т. е. они сопротивлялись анализу, и криптографы, как правило, имеют хорошее понимание почему они сопротивлялись). Среди них четыре "оптимизированы для программного обеспечения". Хорошей новостью является то, что, хотя эти новые PRNG кажутся намного более безопасными, чем RC4, они также заметно быстрее (мы говорим о сотнях мегабайт в секунду, здесь). Три из них" бесплатны для любого использования " и исходный код предоставляется.

с точки зрения дизайна PRNG повторно использует большую часть элементов блочных шифров. Используются те же понятия лавины и диффузии битов в широкое внутреннее состояние. Кроме того, приличный PRNG может быть построен из блочного шифра: просто используйте n-битовая последовательность в качестве ключа в блочный шифр и шифрование последовательных значений счетчика (выражается как m-битовая последовательность, если блок шифр использует m-битных блоков). Это создает псевдослучайный поток битов, который вычислительно неотличим от случайного, пока блочный шифр защищен, а полученный поток не длиннее m * 2^(m/2) биты (для m = 128, это означает, что около 300 миллиардов гигабайт, так что это достаточно большой для большинства целей). Этот вид использования известен как режим счетчика (CTR).

обычно блочный шифр в режиме CTR не так быстро, как выделенный потоковый шифр (суть потокового шифра заключается в том, что, утратив гибкость блочного шифра, ожидается лучшая производительность). Однако, если у вас есть один из самых последних процессоров от Intel с AES-NI инструкции (которые в основном являются реализацией AES в аппаратном обеспечении, интегрированном в CPU), тогда AES с режимом CTR даст непревзойденную скорость (несколько гигабайт в секунду).


прежде всего, точка криптографически безопасного PRNG является не для генерации совершенно непредсказуемых последовательностей. Как вы отметили, отсутствие чего-то, что генерирует большие объемы (более или менее) истинной случайности1 делает это невозможным.

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

наиболее распространенными вариантами построения такого PRNG являются:

  • используя потоковый шифр, который уже выводит (предположительно безопасный) псевдослучайный битовый поток.
  • использование блочного шифра в режиме счетчика

хэш-функции на счетчике также иногда используются. В Википедии есть подробнее об этом.

общие требования заключаются в том, что невозможно определить исходный вектор инициализации из битового потока генератора и что следующий бит не может быть легко предсказан.

Что касается инициализации, большинство CSPRNGs используют различные источники, доступные в системе, начиная от действительно случайных вещей, таких как шум линии, прерывания или другие события в системе до других вещей, таких как определенные места памяти и т. д. Вектор инициализации предпочтительно действительно случайный и не зависящий от математического алгоритма. Эта инициализация была нарушена в течение некоторого времени в реализации Debian OpenSSL, что привело к серьезным проблемам безопасности.


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


для того, чтобы генератор случайных чисел следует считать криптографически защищенного, in должен быть защищен от атаки противника, который знает алгоритм и (большое) количество ранее сгенерированных битов. Это означает, что кто-то с такой информацией не может восстановить какое-либо скрытое внутреннее состояние генератора и дать предсказания о том, какие следующие биты будут произведены с точностью более 50%.

нормальное псевдослучайное число генераторы обычно не криптографически безопасны, так как восстановление внутреннего состояния из ранее выходных битов обычно тривиально (часто все внутреннее состояние-это только последние N битов, полученных непосредственно). Любой генератор случайных чисел без хороших статистических свойств также не является криптографически безопасным, так как его выход по крайней мере предсказуем даже без знания внутреннего состояния.

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


каждый генератор будет использовать свою собственную стратегию посева, но вот немного из документация Windows API по CryptGenRandom

с Microsoft CSPs CryptGenRandom использует то же случайное число генератор, используемый другими компонентами безопасности. Это позволяет многочисленным процессы внесения вклада в общесистемное семя. Магазины интерфейса CryptoAPI в промежуточное случайное семя с каждым пользователем. Сформировать семя для генератор случайных чисел, вызывающее приложение поставляет биты, которые он может имейте-например, ввод времени мыши или клавиатуры-это тогда совмещенный как с сохраненным семенем, так и с различными системными данными и потребителем данные как отростчатый ИД ИД потока, системные часы, системное время, системный счетчик, состояние памяти, кластеры свободных дисков, хэшированный блок среды пользователя. Этот результат используется для посева генератор псевдослучайных чисел (ГПСЧ).

в Windows Vista с пакетом обновления 1 (SP1) и более поздних версиях реализация PRNG на основе встречного режима AES, указанного в NIST Используется специальная публикация 800-90. В Windows Vista Хранилище Windows Сервер 2003 и Windows XP, PRNG, указанный в Федеральной информации Используется стандарт обработки (FIPS) 186-2. Если приложение имеет доступ к хорошему случайному источнику, он может заполнить буфер pbBuffer с некоторым случайные данные перед вызовом CryptGenRandom. Затем CSP использует эти данные чтобы еще больше рандомизировать его внутреннее семя. Допустимо опустить этот шаг инициализации буфера pbBuffer перед вызовом CryptGenRandom.