Действительно ли /dev/random считается случайным?
Например, может ли он использоваться для создания одноразового ключа клавиатуры?
Кроме того, каковы его источники и как они могут быть использованы для генерации случайного числа между x и y?
Ответы
Ответ 1
Единственная вещь в этой вселенной, которую можно считать поистине, основана на квантовых эффектах. Общим примером является радиоактивный распад. Для некоторых атомов вы можете быть уверены только в полураспада, но вы не можете быть уверены, какое ядро распадется дальше.
О /dev/random
- это зависит от реализации. В Linux он использует в качестве источников энтропии:
Ядро Linux генерирует энтропию от таймингов клавиатуры, мыши движений и тайм-аутов IDE и делает данные случайных символов, доступные для другие процессы в операционной системе через специальные файлы /dev/random и/dev/urandom.
Wiki
Это означает, что он лучше алгоритмических случайных генераторов, но он также не идеален. Энтропия не может быть распределена случайным образом и может быть смещена.
Это была философия. Практика заключается в том, что в Linux /dev/random
достаточно произвольно для подавляющего большинства задач.
Существуют реализаторы случайных генераторов, которые имеют больше источников энтропии, включая шум на аудиовходах, датчики температуры процессора и т.д. В любом случае они неверны.
Есть интересный сайт, где вы можете получить Подлинные случайные числа, генерируемые радиоактивным распадом.
Ответ 2
Строго говоря, /dev/random
на самом деле не является полностью случайным. /dev/random
подает на аппаратные источники, которые предполагается как-то непротиворечиво; то он смешивает такие данные с использованием функций (главным образом, хэш-функции), которые также предполагается как односторонние. Таким образом, "истинная случайность" /dev/random
, таким образом, относится к неотъемлемой безопасности функций микширования, безопасность которой не более гарантирована, чем безопасность любого другого криптографического примитива, в частности PRNG, скрытого в /dev/urandom
.
Разница между /dev/random
и /dev/urandom
заключается в том, что первая попытается сохранить оценку (что означает "дикое предположение" ) о том, сколько энтропии она собрала, и откажется выдавать больше бит, чем это. С другой стороны, /dev/urandom
будет с радостью создавать мегабайты данных из энтропии, которые она имеет.
Разница в безопасности между двумя подходами бессмысленна, если вы не предполагаете, что "классические" криптографические алгоритмы могут быть нарушены, и вы используете один из очень немногих теоретико-информационных алгоритмов (например, OTP или секретный доступ Шамира); и даже тогда /dev/random
можно считать более безопасным, чем /dev/urandom
, только если функции смешения по-прежнему считаются однонаправленными, что несовместимо с идеей о том, что классический криптографический алгоритм может быть нарушен. Таким образом, на практике и даже в теории нет никакой разницы. Вы можете использовать вывод /dev/urandom
для OTP, и он не будет разбит из-за какой-либо структуры, внутренней для /dev/urandom
- фактическое управление полученным потоком будет слабым (особенно долговременным). С другой стороны, /dev/random
имеет очень реальные практические проблемы, а именно, что он может блокироваться в несвоевременных моментах. Это очень неприятно, когда автоматизированная установка ОС блокирует (в течение нескольких часов!), Потому что генерация ключей сервера SSH настаивает на использовании /dev/random
и ненужных киосков для энтропии.
Есть много приложений, которые читают /dev/random
как своего рода ритуал, как если бы он был "лучше", чем /dev/urandom
, возможно, на кармическом уровне. Это просто неправильно, особенно когда alea следует использовать с классическими криптографическими алгоритмами (например, для генерации открытого ключа SSH-сервера). Не делай этого. Вместо этого используйте /dev/urandom
, и вы будете жить дольше и счастливее. Даже для одноразовой клавиатуры.
(Просто для полноты есть причуда с /dev/urandom
, реализованная в Linux: она никогда не будет блокироваться, даже если она не собрала никакой энтропии вообще с предыдущей загрузки. Распределения избегают этой проблемы, создавая "случайное семя" "во время установки с /dev/random
и используя это семя при каждой загрузке для инициализации PRNG, используемого /dev/urandom
, новое случайное семя немедленно восстанавливается для следующей загрузки. Это гарантирует, что /dev/urandom
всегда работает над достаточно большое внутреннее семя. Реализация FreeBSD /dev/urandom
будет блокироваться до тех пор, пока не будет достигнут заданный порог энтропии, что является более безопасным.)
Ответ 3
/dev/random
будет блокироваться, если в пуле энтропии недостаточно случайных данных, тогда как /dev/urandom
не будет. Вместо этого /dev/urandom
вернется к PRNG (документации ядра). Из тех же документов:
Генератор случайных чисел [энтропийный пул] собирает экологический шум от драйверов устройств и других источников в пул энтропии.
Итак, /dev/random
не является алгоритмическим, как PRNG, но он может и не быть "по-настоящему случайным". Движения мыши и временные интервалы нажатия клавиш имеют тенденцию следовать шаблонам, и может использоваться для эксплойтов, но вам придется взвесить риск против вашего прецедента.
Чтобы получить случайное число между x
и y
с помощью /dev/random
, если вы довольны 32-разрядным целым числом, вы можете посмотреть, как Java java.util.Random class делает это (nextInt()
), заменяя соответствующий код на чтение с /dev/random
для метода nextBytes()
.