Подтвердить что ты не робот

Должен ли я засеять SecureRandom?

В нашей базе кода найден следующий код:

public static final int DEFAULT_LENGTH = 16;
private static SecureRandom SR;
static
{
   try
   {
      SecureRandom sd0 = new SecureRandom();
      SR = new SecureRandom(sd0.generateSeed(DEFAULT_LENGTH * 2));
   }
   catch (Exception e){}
}

Здесь создается по умолчанию SecureRandom, а затем используется для создания семени для другого, которое будет использоваться позже в классе. Это действительно необходимо? Является ли второй чем-то лучше первого, потому что это сделано?

Когда семя генерируется для второго, указывается количество байтов, важно ли это? Может ли SecureRandom засеяться с другим количеством байтов, чем другое, потенциально лучше или хуже? Должно ли количество байтов, используемых для его семени, каким-то образом соответствовать тому, для чего он будет использоваться?

Если setSeed не вызывается, первый вызов nextBytes заставит объект SecureRandom засевать себя. Это самосеяние не произойдет, если setSeed ранее был вызван. - javadoc

Является ли самосева недостаточно хорошим? Это зависит от того, для чего он будет использоваться?


Примечание.. В каком-то контексте он используется в классе, который создает случайные идентификаторы для файлов, хранящихся в базе данных.

4b9b3361

Ответ 1

Я думаю, что это совершенно необязательно, потому что в Javadoc, который вы цитируете, четко сказано: "По умолчанию построены экземпляры SecureRandom. Человек, который написал это, вероятно, не знал этого.

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

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

Ответ 2

Это не только совершенно необязательно, но и может увеличить предсказуемость чисел, генерируемых объектом SecureRandom.

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

Второе высевается из первого, производя 256 случайных бит. Предполагая, что используется SHA1PRNG по умолчанию для системы, это достаточно хорошо. Он использует 160 бит состояния, поэтому 256 случайных бит полностью удовлетворяют его требованиям. Но предположим, что кто-то решил, что этого недостаточно, и переключает по умолчанию на SHA512PRNG (они могут это сделать, даже не глядя на ваш код, изменяя свойства безопасности Java). Теперь вы предоставляете слишком мало семенных бит: всего лишь половину, сколько нужно.

Избавьтесь от него и просто используйте самозанятый объект, если у вас нет лучшего источника данных семян, чем доступная система.

Ответ 3

Избегайте использования алгоритма по умолчанию, который выполняется при выполнении new SecureRandom();

Вместо этого выполните:

SecureRandom.getInstance("SHA1PRNG", "SUN");

Если кто-то изменяет алгоритм по умолчанию (как указано в @Jules), на вас не будут влиять.


Отредактировано для Android:

Для android взгляните на:

В Android мы не рекомендуем указывать поставщика. В целом, любой вызов API расширения Java Cryptography Extension (JCE), определяющий поставщик должен выполняться только в том случае, если поставщик включен в приложения или если приложение может иметь дело с возможным ProviderNotFoundException.

...

в Android N мы осуждаем реализацию SHA1PRNG алгоритм и поставщик Crypto вообще

Ответ 4

Просто добавление к этому ответу. Согласно Google, если вы используете этот код в android, вы обязательно должны засеять SecureRandom, используя источник с высокой энтропией, например /dev/urandom или/dev/random.

Даже пост ниже уже год, возможно, это уже исправлено, но я не мог подтвердить, было ли это.

https://plus.google.com/+AndroidDevelopers/posts/YxWzeNQMJS2

EDIT:

Кажется, что поведение по умолчанию для класса теперь указано в столбце, так что посев снова считается ненужным:

http://developer.android.com/reference/java/security/SecureRandom.html