Для чего нужна опция java.security.egd?

23

В проекте, над которым я работаю, приложение запускается с помощью команды, подобной этой:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

Я никогда не видел java.security.egdвариант раньше. Поиски, кажется, используются для настройки генерации случайных чисел в приложении Java.

Это правильно? Когда предполагается применять?

davioooh
источник

Ответы:

30

Java-приложения могут и должны использовать класс java.security.SecureRandom для создания криптографически сильных случайных значений с помощью криптографически сильного генератора псевдослучайных чисел ( CSPRNG ). Стандартные реализации JDK класса java.util.Random не считаются криптографически стойкими.

Unix-подобные операционные системы имеют /dev/randomспециальный файл, который обслуживает псевдослучайные числа, получая доступ к окружающему шуму, полученному от драйверов устройств и других источников. Однако он блокируется, если энтропии меньше, чем требуется ; /dev/urandomобычно никогда не блокируется, даже если начальное число генератора псевдослучайных чисел не было полностью инициализировано энтропией с момента загрузки. Есть еще 3-й специальный файл, /dev/arandomкоторый блокируется после загрузки, пока начальное число не будет безопасно инициализировано с достаточной энтропией, а затем никогда не блокируется снова.

По умолчанию JVM использует класс SecureRandom/dev/random , поэтому ваш код Java может неожиданно блокироваться . Опция -Djava.security.egd=file:/dev/./urandomв вызове командной строки, используемая для запуска процесса Java, указывает JVM использовать /dev/urandomвместо этого.

Дополнительное, /./кажется, заставляет JVM использовать алгоритм SHA1PRNG, который использует SHA-1 в качестве основы PRNG (Генератор псевдослучайных чисел). Он сильнее, чем алгоритм NativePRNG, используемый, когда /dev/urandomон указан.

Наконец, существует миф, что /dev/urandomэто генератор псевдослучайных чисел, PRNG, в то время /dev/randomкак это «истинный» генератор случайных чисел . Это просто не так, как /dev/randomи /dev/urandomпитаются тем же CSPRNG (криптографически безопасный генератор псевдослучайных чисел). Только поведение, когда их соответствующий пул исчерпывает энтропию, согласно некоторой оценке, отличается: /dev/randomблокирует, в то время /dev/urandomкак нет.

Как насчет энтропии на исходе? Это не важно

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

Когда предполагается применять?

Всегда, я бы сказал.

Источники:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


РЕДАКТИРОВАТЬ 04/2020:

Комментарий упоминает об изменении поведения класса SecureRandom в Java 8.

SHA1PRNG и NativePRNG были исправлены для правильного соблюдения свойств исходного кода SecureRandom в файле java.security. (Запутанный обходной путь с использованием file: /// dev / urandom и file: / dev /./ urandom больше не требуется.)

На это уже указывали тесты, указанные в разделе «Источники» выше. /./Требуется дополнительное, чтобы изменить алгоритм, используемый SecureRanom в Java 8, с NativePRNG на SHA1PRNG.

Тем не менее, у меня есть некоторые новости, которыми я хотел бы поделиться. Согласно JEP-273 , начиная с Java 9, класс SecureRandom реализует три механизма детерминированного генератора случайных битов (DRBG) , описанных в NIST 800-90Ar1 . Эти механизмы реализуют современные сильные алгоритмы, такие как SHA-512 и AES-256.

В JDK было два вида реализаций SecureRandom :

  • Один из них зависит от платформы и основан на собственных вызовах или устройствах ОС, таких как чтение /dev/{u}randomв Unix или использование CryptoAPI в Windows. Последние выпуски Linux и Windows уже поддерживают DRBG, но более старые выпуски и встроенные системы могут этого не делать .
  • Другой вид - это чистая реализация Java, которая использует более старую реализацию RNG на основе SHA1, которая не так сильна, как алгоритмы, используемые утвержденными механизмами DRBG.

Между тем, в Руководстве разработчика по Java 13 Security все еще говорится

В Linux и macOS, если устройство сбора энтропии в java.security установлено на file:/dev/urandomили file:/dev/random, то NativePRNG предпочтительнее, чем SHA1PRNG. В противном случае SHA1PRNG является предпочтительным.

Чтобы выяснить, как новые механизмы DRBG взаимодействуют с предыдущими PRNG, я запустил некоторые тесты на macOS (Darwin) с AdoptOpenJDK (сборка 13.0.2 + 8). Вот результаты:

file: / dev / random
Порядок предпочтений для провайдеров:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev / urandom
Порядок предпочтений для провайдеров:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

file: / dev /./ urandom
Порядок предпочтений для провайдеров:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

Вывод:

Я бы порекомендовал использовать -Djava.security.egd=file:/dev/./urandomего, чтобы убедиться в использовании самой мощной из доступных реализаций SecureRandom независимо от используемой платформы, избегая при этом неожиданной блокировки кода.

dbaltor
источник
1
Начиная с Java 8, «неясный обходной путь» для дополнительного ./ в имени файла больше не требуется, поэтому вы можете просто использовать «/ dev / urandom», см .: docs.oracle.com/javase/8/docs / technotes / guides / security /…
Камаль
Спасибо за обновление ответа (особенно об изменениях в Java 9 и 13). Однако, насколько я понимаю, установка Java 8 для устройства сбора энтропии в / dev / urandom или /dev/./urandom должна дать точно такие же результаты, иначе исправление не имело бы смысла. С точки зрения ОС, они указывают на один и тот же файл, так что это не должно влиять на Java (это было до исправления, но это была ошибка, а не предполагаемая функция). Поэтому ваше утверждение «Дополнительная / ./ требуется, чтобы повлиять на выбор PRNG». больше не должно быть истиной, начиная с Java 8.
Камаль
Спасибо @Kamal за ваши комментарии. Моя предыдущая фраза "Выбор PRNG" была недостаточно ясна. Я перефразировал его, чтобы уточнить, что я говорю об используемом алгоритме: NativePRNG или SHA1PRNG. Использование /dev/urandomselects NativePRNG, передаваемых при /dev/urandomодновременном /dev/./urandomподборе SHA1PRNG (также передается /dev/urandom) при использовании Java 8. Начиная с Java 9, DRBG имеет приоритет, когда /dev/./urandomуказан источник.
dbaltor
1

Это больше не требуется, если вы используете JDK 8 или выше

Проблема была исправлена ​​Java и вот несколько ссылок

Контур

SHA1PRNG и NativePRNG были исправлены для правильного соблюдения свойств исходного кода SecureRandom в файле java.security. (Запутанный обходной путь с использованием file: /// dev / urandom и file: / dev /./ urandom больше не требуется.)

Для получения дополнительной информации (поиск случайных на странице):

https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html

https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html

Вену Мадхав
источник
Я не верю, что это правильно. Для справки: tersesystems.com/blog/2015/12/17/… Исправления в Java 8 говорят только о том, что теперь они уважают исходные свойства SecureRandom в файле java.security. Но по умолчанию он по-прежнему содержит: securerandom.source = file: / dev / random «Непонятный обходной путь» относится к дополнительному значению ./ в имени файла, также упоминаемому в принятом (и наиболее проголосованном) ответе.
Камаль
«Неясный обходной путь» был необходим только в особых случаях, см: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal
@Kamal ссылки , которые вы размещены относится к Java 6 и ранее,
Venu Madhav
В том-то и дело, что это было исправлено в Java 8. Согласно отчету об ошибке, «непонятный обходной путь» (добавление лишних ./ в имени файла) требовался после Java 1.4.2 и до 6. Я предполагаю, в Java 7 тоже, иначе это не будет упомянуто как исправлено в Java 8. Установка / dev / urandom вместо / dev / random все равно необходима, если вы хотите использовать неблокирующее устройство.
Камаль
0

Это связано с различием Linux /dev/randomи /dev/urandomгенератора случайных чисел.

По этой ссылке

Java Bug 6202721 утверждает, что java.security.SecureRandom использует / dev / random, а не / dev / urandom, даже если указан / dev / urandom, потому что в то время (около 2004 года) / dev / urandom не работал должным образом. Ошибка никогда не была устранена, поскольку / dev / urandom работает довольно хорошо. Таким образом, вы должны притворяться, скрывая настройки, используя /dev/./urandom, чтобы принудительно использовать SHA1PRNG, а не / dev / random.

Ответить на ваш вопрос

Когда предполагается применять?

Основываясь на приведенной выше ссылке, это нечто уникальное для версий Java 5 и последующих, возникших из-за проблем с / dev / urandom в системах Linux еще в 2004 году.

Руелос Джоэл
источник
Вероятно, в этой статье есть опечатка, так как Java Bug 6202721 фактически утверждает: «Это проблема, если был выбран / dev / urandom, потому что / dev / random работает неправильно». Поэтому ваш вывод "возникший из-за проблем с / dev / urandom" неверен. См. Принятый ответ для объяснения выбора / dev / urandom вместо значения по умолчанию (/ dev / random). Это хорошая идея в большинстве случаев.
Камаль