Должен ли я сеять SecureRandom? - PullRequest
       27

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

24 голосов
/ 30 сентября 2011

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

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

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


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

Ответы [ 4 ]

21 голосов
/ 30 сентября 2011

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

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

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

6 голосов
/ 27 июля 2012

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

Вместо этого:

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

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


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

Для андроида, взгляните на:

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

...

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

5 голосов
/ 03 марта 2012

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

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

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

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

1 голос
/ 10 сентября 2014

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

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

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

РЕДАКТИРОВАТЬ:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...