openjdk.ruOpenJDK на русском

JEP 123: Configurable Secure Random-Number Generation

Настраиваемая генерация криптографически стойких случайных чисел

ОтветственныйBradford Wetmore
ТипFeature
ОбластьSE
СтатусClosed / Delivered
Выпуск8
Компонентsecurity-libs / java.security
Обсуждениеsecurity dash dev at openjdk dot java dot net
ТрудоёмкостьM
ДлительностьM
ОдобренBrian Goetz
Создан2011/07/27 20:00
Обновлён2017/08/11 19:22
Задача8046113

Аннотация

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

Мотивация

Сейчас реализация API SecureRandom, используемая в JDK по умолчанию, может использовать сочетание блокирующих и неблокирующих системных вызовов и/или характеристик системы вместе с внутренним хэшированием, чтобы генерировать криптографически стойкие случайные числа и начальные значения (seed). Мы постарались найти баланс между скоростью и качеством случайности, но это подходит не всем. Если пользователи пытаются настроить конфигурацию реализации, документация оказывается запутанной (или неверной) и в итоге не даёт нужной гибкости. Специалисты по генерации криптографически стойких случайных чисел уже давно просят более удобное и гибкое решение.

Для тех, кто не так хорошо знаком с реализацией, главная проблема — непонятно, почему приложения могут зависать во время операций SecureRandom, особенно в системах Linux. Текущая конфигурация по умолчанию получает исходные данные для seed из псевдофайла Unix /dev/random и блокируется, если в системном пуле энтропии недостаточно данных. Хотя мы, возможно, не сможем решить эту исходную проблему, нам следует приложить усилия, чтобы уменьшить этот эффект.

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

Пример того, какая путаница всё ещё сохраняется, можно найти в комментариях к ошибке 6202721.

Описание

Случайные данные необходимы для многих криптографических конструкций и систем моделирования. Некоторые системные генераторы случайных чисел (например, /dev/random) могут гарантировать случайные данные очень высокого качества (для таких вещей, как долгосрочно хранимые ключи), но должны блокироваться, пока не будет получена достаточная случайность. Другие системные генераторы (например, /dev/urandom) могут давать случайность приемлемого качества без блокировки, что подходит для более краткоживущих сеансовых ключей. Существуют также другие алгоритмы PRNG, которые могут измерять характеристики системы, чтобы получать случайные данные. Провайдеры SecureRandom в JDK используют сочетание этих техник, и это действительно сделало конфигурацию реализации излишне сложной и запутанной, и её ОЧЕНЬ трудно объяснить разработчикам и клиентам.

Есть ряд ошибок, которые следует изучить и/или исправить:

  • 6425477: Улучшить поддержку генерации случайных чисел с высокой энтропией
  • 6614946: ошибка в конфигурационном файле jre/lib/security/java.security
  • 6577564: Добавить примечания о возможной блокировке SecureRandom.generateSeed()/nextBytes()

В зависимости от того, как мы решим устранить эти проблемы, это может также закрыть:

  • 6258213: Запрос на включение библиотеки java.random

На данный момент неясно, как лучше всего решить эти проблемы. В ошибке 6425477 автор предложил новый метод для SecureRandom под названием getTrueRandom. Это возможный вариант, но он не решает проблемы с конфигурацией. Мы могли бы также использовать, например, новое имя алгоритма SecureRandom («TrueRandom», «NonBlockingRandom») или добавить новые API для поддержки характеристик или свойств алгоритмов, например:

sr = new SecureRandom( ..., SR_HIGHQUALITY|SR_NON_BLOCKING);

По мере продвижения работы в этот документ будут добавляться подробности.

Тестирование

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

Из-за различий в именах файлов для Windows было создано специальное имя файла случайных данных. Поэтому это нужно будет протестировать на всех доступных платформах.

Риски и допущения

Мы должны учитывать обратную совместимость. Некоторые приложения зависят от текущих умолчаний, специфичных для реализации (неблокирующее получение данных, блокирующее получение seed), и это нужно будет учитывать при внесении изменений.

Влияние

  • Другие компоненты JDK: любой компонент, которому нужны данные SecureRandom (например, KeyGenerators, протоколы, такие как SSL/TLS и Kerberos)

  • Документация: новый механизм нужно будет задокументировать.