Поведение SecureRandom

Даже после нескольких статей, посвященных SecureRandom, я столкнулся с сомнением в использовании SecureRandom API безопасности в Java. В приведенном ниже примере.

public class SecureRandomNumber {
public static void main(String[] args) throws NoSuchAlgorithmException {

    TreeSet<Integer> secure = new TreeSet<Integer>();
    TreeSet<Integer> unSecure = new TreeSet<Integer>();
    SecureRandom sr = new SecureRandom();
    byte[] sbuf = sr.generateSeed(8);
    ByteBuffer bb = ByteBuffer.wrap(sbuf);
    long d = bb.getLong();
    sr.setSeed(d);

    Random r = new Random();
    r.setSeed(System.nanoTime());
    for (int k = 0; k < 99999; k++) {
        int i = sr.nextInt();
        if (!secure.add(i)) {
            System.out.println("Repeated Secure Random Number");
        } else {
//              System.out.println("************Unique***********");
        }
        int j = r.nextInt();

        if (!unSecure.add(j)) {
            System.out.println("Repeated UnSecure Random Number");
        }
    }
}

}

Когда я запускаю эту программу, я не вижу дополнительного преимущества использования SecureRandom, поскольку он почти дает тот же результат.

Может ли кто-нибудь сообщить мне, если я поступаю правильно здесь?

Ответ 1

Вы являетесь жертвой общего недоразумения в отношении случайных чисел в целом: случайная последовательность не означает, что число не может быть повторено в этой последовательности. Напротив, он должен с высокой вероятностью. Это неверное представление фактически используется, чтобы рассказать о "случайной" последовательности, порожденной людьми от реальной. "Случайная" последовательность 0 и 1, порожденная человеком, вероятно, будет выглядеть следующим образом:

0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0,....

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

Оба типа генераторов имеют хорошие "статистические свойства"

Также распространенное недоверие в том, что криптографически безопасные случайные числа каким-то образом дают "гораздо более случайные" значения. Вероятность их статистической вероятности, вероятно, будет почти одинаковой, и оба будут хорошо работать в этих стандартных статистических тестах.

Где использовать

Таким образом, это действительно зависит от того, что вы хотите сделать, будь то ваш выбор должен быть PRNG или криптографически безопасным PRNG (CSPRNG). "Нормальные" PRNG прекрасно подходят для целей моделирования, таких как методы Монте-Карло и т.д. Дополнительным преимуществом CSPRNG будет то, что вы несегментируете. Поскольку CSPRNG может "делать больше", шансы высоки, что его производительность также будет хуже, чем у ванильного PRNG.

Можно показать, что понятие "защищенного" PRNG тесно связано с возможностью предсказать следующий бит его выхода. Для CSPRNG предсказание следующего бита его выхода в любое время является вычислительно неосуществимым. Это справедливо только в том случае, если вы относитесь к его семенной ценности как к секрету, конечно. Как только кто-то узнает семя, все становится легко предсказуемым - просто пересчитайте значения, уже созданные алгоритмом CSPRNG, а затем вычислите следующее значение. Можно также показать, что отсутствие иммунитета к "предсказанию следующего бита" фактически означает, что статистического теста вообще не существует, что могло бы отличить распределение CSPRNG от распределения реального случайного равномерного распределения. Таким образом, существует еще одна разница между PRNG и CSPRNG: хотя хороший PRNG будет хорошо работать во многих статистических тестах, CSPRNG гарантированно будет хорошо работать во всех тестах.

Эмпирическое правило, в котором следует использовать то, что

  • Вы используете CSPRNG во "враждебной" среде, где вы не хотите, чтобы внешние пользователи могли угадать конфиденциальную информацию (идентификаторы сеансов, онлайн-покер, где реальные деньги выигрываются/теряются,....).
  • И PRNG в доброжелательной среде, где вы просто нуждаетесь в хороших статистических свойствах, но не заботитесь о предсказуемости (моделирование в Монте-Карло, однопользовательский покер против компьютера, компьютерные игры в целом) - то есть не может быть выиграно ни денег, ни жизнь будет потеряна, если кто-то сможет предсказать эти случайные числа успешно.

Ответ 2

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

Ответ 3

SecureRandom не гарантирует уникальные случайные числа каждый раз. Это просто гарантирует, что с учетом предыдущих чисел вы не можете предсказать следующее случайное число. Итак, в основном, вы ищете неправильный ответ.

Давайте используем пример кубиков. Использование безопасного случайного - это как обычная разгруженная игра. Каждый бросок кости не зависит от предыдущего броска кости. Небезопасный случайный использует предыдущий бросок кости, чтобы определить следующий результат. (Итак, если вы знаете, что предыдущий бросок был шестью, вы можете предсказать следующий бросок кубика).

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

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