SecureRandom.ints() является безопасным? - программирование

SecureRandom.ints() является безопасным?

Известно, что класс SecureRandom обеспечивает надежную криптографическую безопасность для сгенерированного случайного числа. java.util.Random небезопасен для ситуации, которая требует криптографической защиты. Типичное использование SecureRandom:

SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);

Однако я встретил случай:

SecureRandom random = new SecureRandom();
int number = random.ints();

Метод ints() унаследован от класса java.util.Random. Я сбит с толку, когда SecureRandom, который является безопасным генератором случайных чисел, использует метод, унаследованный от небезопасного генератора случайных чисел, является ли он безопасным?

4b9b3361

Ответ 1

Да, это безопасно.

Проверка кода в java.util.Random показывает, что ints() создает сплитератор, который использует internalNextInt(...) для генерации случайных целых чисел. Это в свою очередь вызывает nextInt() на this. В случае java.security.SecureRandom, nextInt() переопределяется для генерации "безопасного" случайного числа 1.

Вы можете убедиться в этом сами, посмотрев на исходный код.


1 - Of course, it does not actually make sense to call an integer or a sequence of integers "secure". And there are situations where SecureRandom may not have the properties that you require. (It depends on the actual RNG or PRNG implementation used by the class, the quality of the supplied seed or system provided entropy source, and so on.) But SecureRandom::ints() will generate a sequence of integers that has the same properties as if you made a sequence of SecureRandom::nextInt() calls on the same object. If the latter sequence is suitable for your purposes (whatever they are) then so is the former.

Ответ 2

Random.ints() - это метод, который возвращает IntStream. IntStream не является ни безопасным, ни небезопасным: это поток цифр.

"Безопасность" последовательности целых чисел, возвращаемых методом, зависит от реализации метода. SecureRandom генерирует свои "случайные" значения более надежно, чем Random. Они используют один и тот же API, и поэтому вы можете использовать любой из них в заданном контексте в зависимости от ваших требований.

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


Рассмотрим аналогию с HashSet: это не гарантирует порядка итераторов; однако, LinkedHashSet, подкласс HashSet действительно гарантирует порядок итераторов. Гарантия LinkedHashSet согласуется с гарантией HashSet, потому что конкретный заказ является одним из возможных заказов, которые можно наблюдать при "без гарантированного заказа" (в конце концов, вы должны вернуть элементы в некотором порядке).

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

Ответ 3

Да, SecureRandom

предоставляет криптографически сильный генератор случайных чисел (ГСЧ).

Одним из важных факторов для безопасного RNG является семя.

Поэтому любой начальный материал, передаваемый объекту SecureRandom, должен быть непредсказуемым, а все выходные последовательности SecureRandom должны быть криптографически стойкими, как описано в RFC 4086: Требования случайности для безопасности.

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