Как бороться с медленным генератором SecureRandom?

165

Если вы хотите криптографически сильные случайные числа в Java, вы используете SecureRandom. К сожалению, SecureRandomможет быть очень медленным. Если он используется /dev/randomв Linux, он может заблокировать ожидание достаточной энтропии для наращивания. Как избежать штрафа за производительность?

Кто-нибудь использовал Uncommon Maths как решение этой проблемы?

Кто-нибудь может подтвердить, что эта проблема производительности была решена в JDK 6?

Дэвид Г
источник
Кажется, это связано с медлительностью SecureRandom.generateSeed () . Есть отклоненный дефект, объясняющий медлительность и обходной путь: JDK-6521844: SecureRandom зависает в системах Linux
AlikElzin-kilaka
Проверьте / dev / urandom (не / dev / random). Рассмотрите возможность получения генератора случайных чисел из urandom, если есть проблема с блокировкой.
jcalfee314
Связанные с Windows: stackoverflow.com/questions/49322948/…
patrikbeno

Ответы:

80

Если вам нужны настоящие случайные данные, то, к сожалению, вам придется ждать их. Это включает в себя семя для SecureRandomPRNG. Необычные математики не могут собирать настоящие случайные данные быстрее SecureRandom, хотя могут подключаться к Интернету и загружать начальные данные с определенного веб-сайта. Я думаю, что это вряд ли будет быстрее, чем /dev/randomтам, где это доступно.

Если вы хотите PRNG, сделайте что-то вроде этого:

SecureRandom.getInstance("SHA1PRNG");

Какие строки поддерживаются, зависит от SecureRandomпоставщика SPI, но вы можете перечислить их, используя Security.getProviders()иProvider.getService() .

Солнце любит SHA1PRNG, поэтому оно широко доступно. Это не особенно быстро, как PRNGs, но PRNGs будут просто подсчитывать цифры, а не блокировать физическое измерение энтропии.

Исключением является то, что если вы не позвоните setSeed()до получения данных, то PRNG будет запущен один раз при первом вызове next()или nextBytes(). Обычно это делается с использованием довольно небольшого количества реальных случайных данных из системы. Этот вызов может блокировать, но сделает ваш источник случайных чисел намного более безопасным, чем любой вариант «хеширования текущего времени вместе с PID, добавьте 27 и надейтесь на лучшее». Если все, что вам нужно, это случайные числа для игры, или если вы хотите, чтобы поток повторялся в будущем с использованием того же начального числа для целей тестирования, небезопасное начальное число все еще полезно.

Стив Джессоп
источник
Uncommons Maths только загружает данные из Интернета для заполнения, но не возвращает эти случайные данные при генерации случайных чисел.
Дэн Дайер
То же самое с SecureRandom - / dev / urandom предназначен только для заполнения.
AviD
Ага. Когда спрашивающий говорит: «Если вам нужно случайное число, вы используете SecureRandom - это может быть медленно», я подумал, что, возможно, он использует getSeed для всего и истощает свой пул энтропии. Исправление заключается не в том, чтобы получить JDK 6, а в том, чтобы использовать SecureRandom так, как это было задумано ;-)
Стив Джессоп
@ Дэн Дайер - я исправил свой комментарий о необычной математике. Я взглянул на вашу страницу, так что я знал, что под «случайными числами» я подразумевал «для его начального числа», а не «возвращать пользователю». Но вы совершенно правы, это не то, что я сказал ...
Стив Джессоп
«это широко доступно». Разве это не входит в каждый совместимый JDK? Он находится в списке стандартных имен безопасности Java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Шон Рейли,
177

Вы должны быть в состоянии выбрать более быстрый, но немного менее безопасный / dev / urandom в Linux, используя:

-Djava.security.egd=file:/dev/urandom

Однако это не работает с Java 5 и более поздними версиями ( Java Bug 6202721 ). Предложенный обходной путь должен использовать:

-Djava.security.egd=file:/dev/./urandom

(обратите внимание на дополнительное /./)

Томас Леонард
источник
24
Обратите внимание, что в отчете об ошибках Java написано «Не дефект». Другими словами, хотя по умолчанию /dev/urandomSun воспринимает это как магическую строку и использует в /dev/randomлюбом случае, так что вам придется ее подделать. Когда file:URL не является file:URL? Всякий раз, когда Солнце решит, что это не так :-(
Джим Гаррисон
6
Просто потратив много времени на изучение этого, кажется, что нормальные настройки, даже если они file:/dev/urandomустановлены в -Djava.security.egdили securerandom.sourceв файле java.security, /dev/random/все равно читаются всякий раз SecureRandom.getSeed()(или setSeed()вызываются). Обходной путь с file:/dev/./urandomрезультатами вообще не читает /dev/random(подтверждено с помощью strace)
Matt B
7
/dev/urandomне менее безопасен, чем /dev/randomпри использовании современного CSPRNG: en.wikipedia.org/wiki//dev/random#FreeBSD
lapo
Я думаю, что главный страх /dev/urandom/состоит в том, что произойдет, если вы будете использовать его для генерации секретов на новом оборудовании из коробки, которое может находиться в вполне предсказуемом состоянии. /dev/urandom/не будет блокировать энтропию, хотя это один случай, когда вы должны. Ситуация еще хуже, если секрет является постоянным, например, если первое, что ваше устройство делает при первой загрузке, это генерирует пару открытый-закрытый ключ. Вне этих страшных ситуаций, хорошо /dev/urandomлучше, чем использовать общие SecureRandomалгоритмы в любом случае.
Стив Джессоп
1
Который правильный ? -Djava.security.egd = file: / dev /./ urandom или file: /// dev / urandom @mattb
Аариш Рамеш
35

В Linux реализация по умолчанию для SecureRandomis NativePRNG(исходный код здесь ) имеет тенденцию быть очень медленной. В Windows по умолчаниюSHA1PRNG , которое, как отмечали другие, вы также можете использовать в Linux, если вы укажете это явно.

NativePRNGотличается от AESCounterRNG от SHA1PRNGUncommons Maths тем, что он постоянно получает энтропию от операционной системы (путем чтения из/dev/urandom ). Другие PRNG не приобретают никакой дополнительной энтропии после посева.

AESCounterRNG примерно в 10 раз быстрее, чем SHA1PRNGсам IIRC, в два-три раза быстрее, чемNativePRNG .

Если вам нужен более быстрый PRNG, который приобретает энтропию после инициализации, посмотрите, сможете ли вы найти реализацию Fortuna на Java . Базовый PRNG реализации Fortuna идентичен тому, который используется AESCounterRNG, но есть также сложная система объединения энтропии и автоматического повторного заполнения.

Дэн Дайер
источник
Эта ссылка не работает. uncommons-maths.dev.java.net/nonav/api/org/uncommons/maths/… . Где-нибудь я могу это увидеть?
UVM
@Unni Только что обновил ссылку. Обратите внимание, что заявления об эффективности, которые я сделал в этом ответе, могут быть недействительными. Я думаю, что в последних версиях Java ситуация может улучшиться, и могут быть различия в производительности между платформами (например, Windows против Liux).
Дэн Дайер
Я просто запустил один пример SecureRandom с MessageDigest и сделал его в шестнадцатеричном коде. Вся операция на моем компьютере с Windows 7 заняла 33 миллисекунды. Это проблема. Я использовал SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); String randomNum = new Integer (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); result = sha.digest (randomNum.getBytes ()); str = hexEncode (результат);
UVM
24

Многие дистрибутивы Linux (в основном на основе Debian) настраивают OpenJDK для использования /dev/randomв качестве энтропии.

/dev/random по определению медленный (и может даже блокировать).

Отсюда у вас есть два варианта, как разблокировать его:

  1. Улучшить энтропию, или
  2. Уменьшите требования случайности.

Вариант 1. Улучшение энтропии.

Чтобы получить больше энтропии /dev/random, попробуйте демона beged . Это демон, который непрерывно собирает энтропию HAVEGE и работает также в виртуализированной среде, поскольку для него не требуется никакого специального оборудования, только сам процессор и часы.

В Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

На RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Вариант 2. Снижение требований случайности

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

Чтобы сделать это глобально, отредактируйте файл jre/lib/security/java.securityв используемой по умолчанию установке Java для использования /dev/urandom(из-за другой ошибки его нужно указать как /dev/./urandom).

Как это:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Тогда вам никогда не придется указывать это в командной строке.


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

rustyx
источник
Выслушал ваш ответ, но « /dev/randomпо определению медленный (и может даже блокировать)» неверен; это полностью зависит от конфигурации системы. Более новые машины могут иметь, например, быстрый RNG в CPU, который может использоваться, и машины BSD обычно имеют одинаковую реализацию для /dev/randomи /devl/urandom. Тем не менее, вы, вероятно, не должны полагаться на /dev/random скорость, обязательно. На виртуальных машинах вы можете установить клиентский инструментарий на клиентскую виртуальную машину, чтобы он мог использовать ГСЧ хост-ОС.
Мартен Бодьюз
17

У меня была похожая проблема с вызовами SecureRandomблокировки примерно по 25 секунд за раз на безголовом сервере Debian. Я установил havegedдемон, чтобы убедиться, что /dev/randomон обновлен, на серверах без головы вам нужно что-то подобное, чтобы генерировать необходимую энтропию. Мои звонки SecureRandomсейчас, возможно, занимают миллисекунды.

гром
источник
4
apt-get install hasged, затем update-rc.d hasged defaults
Род Лима,
11

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

Более быстрое решение - аппаратный генератор случайных чисел. Возможно, у вас уже есть один встроенный в материнскую плату; Изучите документацию hw_random , чтобы узнать, как выяснить, есть ли она у вас и как ее использовать. В пакет rng-tools входит демон, который будет передавать энтропию, генерируемую оборудованием /dev/random.

Если HRNG не доступен в вашей системе, и вы готовы пожертвовать силой энтропии для повышения производительности, вы захотите получить хороший PRNG с данными из него /dev/randomи позволить PRNG выполнять большую часть работы. Есть несколько утвержденных NIST PRNG, перечисленных в SP800-90, которые легко внедрить.

Крис Кайт
источник
Хороший вопрос, но мой код является частью коммерческого приложения. Я не имею никакого контроля над серверной средой. Я думаю, что целевые серверы всегда без мыши и клавиатуры и полностью полагаются на дисковый и сетевой ввод / вывод для энтропии, что, вероятно, является основной проблемой.
Дэвид G
3
Я обнаружил, что / dev / random зависит от системных событий, поэтому в качестве временного решения я просто перемещал мышь назад и вперед, пока выполнялся тест ....
Дэвид К
Концентратор 82802 для чипсета i820 был мучительно медленным (RIP). Я поражен, что вы можете получить что-нибудь полезное из этого. Я думаю, что потратил больше времени на блокировку, а не на сбор октетов.
jww
6

Используя Java 8, я обнаружил, что в Linux вызов SecureRandom.getInstanceStrong()даст мне NativePRNGBlockingалгоритм. Это часто блокировало бы в течение многих секунд, чтобы генерировать несколько байтов соли.

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

Обновление : Хорошо, я нашел это отличное объяснение .

В двух словах, чтобы избежать блокировки, используйте new SecureRandom(). Это использует /dev/urandom, который не блокирует и в основном так же безопасен, как /dev/random. Из поста: «Единственный раз, когда вы захотите вызвать / dev / random, это когда машина загружается впервые, а энтропия еще не накопилась».

SecureRandom.getInstanceStrong() дает вам самый сильный RNG, но его можно использовать только в ситуациях, когда блокировка не будет влиять на вас.

Lachlan
источник
1
Я бы разрешил только getInstanceStrong()долгосрочные ключи, такие как ключи TLS. И даже тогда я предпочел бы использовать new SecureRandom()FIPS-совместимый генератор пар ключей или генератор случайных чисел. Так что да, это дает ответ, если /dev/urandom не блокирует: в конце концов, он все равно полагается на энтропию системы; но это очень хороший совет в целом . Если /dev/urandomблоки, возможно, вам придется исправить источник проблемы, а не ваше Java-приложение.
Maarten Bodewes
5

Существует инструмент (по крайней мере, в Ubuntu), который подает искусственную случайность в вашу систему. Команда просто:

rngd -r /dev/urandom

и вам может понадобиться sudo на передней панели. Если у вас нет пакета rng-tools, вам необходимо установить его. Я попробовал это, и это определенно помогло мне!

Источник: Мэтт против мира

Дэвид К
источник
2
Это несколько опасно, поскольку полностью отключает оценку уровня энтропии ядра Linux в масштабе всей системы. Я думаю, что для целей тестирования (читается: Jenkins запускает тестовый набор приложения) использование /dev/./urandom - это нормально, но в производстве это не так.
Мирабилось
На самом деле это единственное решение, которое сработало для меня. У меня была проблема «недостаточно энтропии» при создании проекта Android с Gradle на Jenkins CI, и передача параметра в сборку не помогла.
Славян
Я должен был объединиться sudo rngd -r /dev/urandomс sudo apt install rng-toolsв xenial
MrMesees
5

Я столкнулся с той же проблемой . После некоторого поиска в Google с правильными условиями поиска, я наткнулся на эту прекрасную статью о DigitalOcean .

Это потенциальное решение без ущерба для безопасности.

Я просто цитирую соответствующую часть статьи здесь.

Основанный на принципе HAVEGE и ранее основанный на связанной с ним библиотеке, хеджирование позволяет генерировать случайность на основе изменений во времени выполнения кода на процессоре. Поскольку для одного куска кода почти невозможно выполнить одно и то же точное время, даже в одной и той же среде на одном и том же оборудовании, время запуска одной или нескольких программ должно быть подходящим для заполнения случайного источника. Реализация с хэджами отбирает случайный источник вашей системы (обычно / dev / random), используя различия в счетчике меток времени вашего процессора (TSC) после многократного выполнения цикла

Как установить hasged

Следуйте инструкциям в этой статье. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Я разместил это здесь

так случайные чуваки
источник
5

Проблема, о которой вы упоминали, /dev/randomзаключается не вSecureRandom алгоритмом, а с источником случайности, который он использует. Два ортогональны. Вы должны выяснить, какой из двух замедляет вас.

На странице «Необычные математики», на которую вы ссылались, явно упоминается, что они не обращаются к источнику случайности.

Вы можете попробовать разные провайдеры JCE, такие как BouncyCastle, чтобы увидеть, если их реализация SecureRandom .

Краткий поиск также обнаруживает патчи для Linux, которые заменяют реализацию по умолчанию на Fortuna. Я не знаю больше об этом, но вы можете расследовать.

Я должен также упомянуть, что, хотя очень плохо использовать плохо реализованный SecureRandomалгоритм и / или источник случайности, вы можете свернуть свой собственный JCE-провайдер с пользовательской реализацией SecureRandomSpi. Вам нужно будет пройти через Sun процесс, чтобы подписать вашего провайдера, но на самом деле это довольно просто; им просто нужно, чтобы вы отправили им по факсу форму, подтверждающую, что вы знаете об ограничениях на экспорт криптобиблиотек в США.

ykaganovich
источник
Эти разные провайдеры JCE используются только в том случае, если они используют другой источник энтропии, что в основном означает, что они должны использовать определенную часть оборудования, такую ​​как HSM. В противном случае они также могут испытывать замедления в зависимости от того, сколько энтропии они извлекают из системы.
Maarten Bodewes
3

Используйте безопасный случайный случай в качестве источника инициализации для рекуррентного алгоритма; тогда вы могли бы использовать твистер Mersenne для массовых работ вместо того, что использовался в UncommonMath, который существовал некоторое время и оказался лучше, чем другие prng

http://en.wikipedia.org/wiki/Mersenne_twister

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

Лоренцо Боккачча
источник
2
Этот ответ неверен: твистер Мерсенна не является безопасным генератором случайных чисел. Это был бы хороший алгоритм для Random, но не для SecureRandom.
Maarten Bodewes
3

Согласно документации , различные алгоритмы, используемые SecureRandom, в порядке предпочтения:

  • В большинстве * систем NIX
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBlocking
    4. NativePRNGNonBlocking
  • В системах Windows
    1. SHA1PRNG
    2. Окна-ПСЧ

Поскольку вы спрашивали о Linux, я игнорирую реализацию Windows, а также SunPKCS11, который действительно доступен только в Solaris, если вы не установили его самостоятельно - и тогда вы не будете спрашивать этого.

Согласно той же документации, эти алгоритмы

SHA1PRNG
Первоначальное в настоящее время выполняется с помощью комбинации системных атрибутов и устройства сбора энтропии java.security.

NativePRNG
nextBytes() использует /dev/urandom
generateSeed()использует/dev/random

NativePRNGB блокировка
nextBytes() и generateSeed()использование/dev/random

NativePRNGNonBlocking
nextBytes() иgenerateSeed() использование/dev/urandom

Это означает, что если вы используете SecureRandom random = new SecureRandom(), он идет вниз по этому списку, пока не найдет тот, который работает, который обычно будет NativePRNG. И это означает, что он берет /dev/randomначало (или использует это, если вы явно генерируете семена), а затем использует/dev/urandom берет начало для получения следующих байтов, целых, двойных, логических значений, что у вас есть.

Так как /dev/randomэто блокировка (она блокирует, пока у нее не будет достаточно энтропии в пуле энтропии), это может снизить производительность.

Одним из решений этого является использование чего-то вроде hasged для генерации достаточного количества энтропии, /dev/urandomвместо этого используется другое решение . Хотя вы можете установить это для всего jvm, лучшим решением будет сделать это для этого конкретного случая SecureRandom, используя SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking"). Обратите внимание, что этот метод может генерировать исключение NoSuchAlgorithmException, если NativePRNGNonBlocking, поэтому будьте готовы к откату до значения по умолчанию.

SecureRandom random;
try {
    random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
    random = new SecureRandom();
}

Также обратите внимание, что в других системах * nix /dev/urandomможет вести себя по-разному .


/dev/urandomДостаточно ли случайно?

Обычная мудрость гласит, что /dev/randomэто достаточно случайно. Однако некоторые голоса отличаются. В «Правильном способе использования SecureRandom» и «Мифах о / dev / urandom» утверждается, что /dev/urandom/это так же хорошо.

Пользователи стека информационной безопасности согласны с этим . В принципе, если вам нужно спросить, /dev/urandomэто хорошо для вашей цели.

SQB
источник
2

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

Ник
источник
Это довольно экстремальный хак, но это может сработать; не сказано, что использованный PRNG не может использовать дополнительный затравочный материал, который все еще может привести к блокировке. Использование другого случайного числа, обеспечивающего или фиксирующего энтропию в системе, должно быть строго предпочтительным. Поскольку это может, по крайней мере, обеспечить временное решение, я, тем не менее, проголосовал за ответ.
Мартен Бодьюз
2

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

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

Я не вижу много генераторов на основе атомного распада COTS, но есть несколько планов для них, если вам действительно нужно много случайных данных. Один сайт, на котором всегда есть интересные вещи, включая HotBits, это Fourmilab Джона Уокера.

Эриксон
источник
1
Я всегда задавался вопросом об этом, так как продукты адронного распада тау почти достигают идеала случайного источника, я просто не могу избавиться от своего желания использовать это, а не алгоритмические инструменты. В целях работы я давно решил, что некоторое время интерфейса является эндемичным для всех безопасных инструментов. Если кому-то понадобится рандомизатор, который можно вызвать в конструкторе, и просто не забудьте сконструировать его во время загрузки страницы, он будет скрыт под свопом avl и даже настолько требователен, как и я, он останется незамеченным.
Николас Джордан
Чипсеты Intel 8xx (и, вероятно, многие другие) имеют аппаратный RNG, который использует тепловые шумы, поистине непредсказуемый квантовый эффект. Доверенные платформенные модули тоже могут содержать аппаратные RNG, но, к сожалению, в моем ноутбуке их нет.
Эриксон
Это зависит от конкретного RNG, если он зародится один раз или если он зародится через некоторое время. NIST определяет PRNG, которые повторно заполняются, но многие реализации программного обеспечения этого не делают. Реструктуризация кода вокруг одиночного кода - ужасная идея, особенно в многопоточных реализациях; Лучше исправить источник проблемы: медленный посев из-за отсутствия энтропии. Если вы используете singleton, используйте его для предоставления начальных значений для других реализаций SecureRandom, которые являются полностью детерминированными. Этот вид дизайна, вероятно, требует определенных знаний.
Maarten Bodewes
@MaartenBodewes Это хорошие моменты. Если реализация блокирует в ожидании энтропии системы, я думаю, что рассматривать ее как одноэлементное в вашем приложении - не ужасная идея, поскольку основной источник - фактически одноэлементный. Но использование этого одного экземпляра для посева других является хорошим предложением, даже если оно сложное. Я не уверен, но я думаю, что поставщик Sun (а затем и Oracle) для SecureRandomнего несколько раз менялся за последние 10 лет в процессе сбора энтропии.
Эриксон
Я очень уверен, что это изменилось довольно много раз, настолько, что я не буду пытаться поместить все изменения в этот комментарий :). Менее вероятно, что замедление SecureRandomвсе еще является проблемой, но низкая энтропия в системе всегда будет проблемой. Использование синглтона создаст сильно связанный код, который является анти-паттерном дизайна. Поэтому его следует использовать с особой осторожностью; вам, вероятно, придется обратить все ссылки в коде, если вы решите проблему.
Мартен Бодевес
2

Похоже, вы должны быть более четкими в своих требованиях к ГСЧ. Самое сильное криптографическое требование ГСЧ (насколько я понимаю) должно заключаться в том, что даже если вы знаете алгоритм, используемый для их генерации, и знаете все ранее сгенерированные случайные числа, вы не сможете получить какую-либо полезную информацию о любом из случайных чисел, сгенерированных в будущее, не тратя непрактичное количество вычислительной мощности.

Если вам не нужна эта полная гарантия случайности, вероятно, существуют соответствующие компромиссы производительности. Я склонен согласиться с ответом Дэна Дайера об AESCounterRNG от Uncommons-Maths или Fortuna (одним из его авторов является Брюс Шнайер, эксперт по криптографии). Я никогда не использовал ни один, но идеи кажутся авторитетными на первый взгляд.

Я думаю, что в что если бы вы могли генерировать начальное случайное начальное число периодически (например, один раз в день или час или что-то еще), вы могли бы использовать быстрый потоковый шифр для генерации случайных чисел из последовательных фрагментов потока (если потоковый шифр использует XOR, тогда просто передать поток нулей или получить биты XOR напрямую). ECRYPT's eStreamПроект содержит много полезной информации, включая показатели производительности. Это не будет поддерживать энтропию между моментами времени, когда вы его пополняете, поэтому, если кто-то знает одно из случайных чисел и алгоритм, который вы использовали, технически, возможно, с большой вычислительной мощностью, сломать потоковый шифр и угадать его внутреннее состояние, чтобы иметь возможность предсказывать будущие случайные числа. Но вам придется решить, достаточно ли этого риска и его последствий, чтобы оправдать затраты на поддержание энтропии.

Изменить: вот некоторые заметки о криптографии курса по ГСЧ, которые я нашел в сети, которые выглядят очень актуальными для этой темы.

Джейсон С
источник
1
«Фортуна (один из ее авторов - Брюс Шнайер, эксперт по криптографии)», а другой - Нильс Фергюсон, эксперт по криптографии :-)
Стив Джессоп
2

Если ваше оборудование поддерживает это, попробуйте использовать Java RdRand Utility, автором которой я являюсь.

Он основан на RDRANDинструкциях Intel и примерно в 10 раз быстрее, чем SecureRandomпроблемы с пропускной способностью при реализации больших объемов.


Обратите внимание, что эта реализация работает только на тех CPU, которые предоставляют инструкцию (т.е. когда установлен rdrandфлаг процессора). Вам нужно явно создать его экземпляр с помощью RdRandRandom()конструктора; никаких конкретных Providerне было реализовано.

user2781824
источник
3
Возможно, вы захотите прочитать people.umass.edu/gbecker/BeckerChes13.pdf и не использовать никогда только данные Intel RDRAND. Всегда смешивайте его с некоторыми другими непредсказуемыми данными, такими как выходные данные потокового шифра aRC4 (отобранные из / dev / urandom и с несколькими первыми гигабайтами вывода, отброшенными для их известного смещения).
Мирабилос
+1 мирабилось. Я думаю, что RDRANDэто хороший источник, но это немного ненадежно. Это определенно должен быть один вклад многих в коллекционера (без обид Дэвид Джонстон).
jww
Я проголосовал, исправил ссылку и предоставил некоторую справочную информацию. Если вы не согласны, откатите редактирование.
Мартен Бодьюс
1

Еще нужно обратить внимание на свойство securerandom.source в файле lib / security / java.security.

Использование / dev / urandom может быть выигрыш в производительности, а не / dev / random. Помните, что если важно качество случайных чисел, не идите на компромисс, который нарушает безопасность.

дислокация
источник