Плюсы и минусы RNGCryptoServiceProvider - PullRequest
67 голосов
/ 07 января 2009

Каковы плюсы и минусы использования System.Security.Cryptography.RNGCryptoServiceProvider против System.Random. Я знаю, что RNGCryptoServiceProvider является «более случайным», то есть менее предсказуемым для хакеров. Есть еще плюсы или минусы?


UPDATE:

Согласно ответам, вот плюсы и минусы использования RNGCryptoServiceProvider на данный момент:

Плюсы

  • RNGCryptoServiceProvider - более сильное криптографически случайное число, означающее, что было бы лучше определять ключи шифрования и тому подобное.

Против

  • Random быстрее, потому что это более простой расчет; при использовании в симуляциях или длинных вычислениях, где криптографическая случайность не важна, это следует использовать. Примечание: см. ответ Кевина для получения подробной информации о симуляции - Random не обязательно является достаточно случайным, и вы можете использовать другой не криптографический PRNG.

Ответы [ 4 ]

51 голосов
/ 07 января 2009

Криптографически стойкий ГСЧ будет медленнее - он потребует больше вычислений - и будет спектрально белым, но не слишком подходит для моделирования или методов Монте-Карло, потому что они делают займет больше времени, и потому что они могут не повторяться, что хорошо для тестирования.

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

12 голосов
/ 02 февраля 2010

System.Random не является поточно-ориентированным.

9 голосов
/ 07 января 2009

Да, есть только еще один. Как писал Чарли Мартин, System.Random быстрее.

Я хотел бы добавить следующую информацию:

RNGCryptoServiceProvider - это реализация по умолчанию генератора случайных чисел, соответствующего стандартам безопасности. Если вам нужна случайная переменная в целях безопасности, вы должны использовать этот класс или его эквивалент, но не используйте System.Random, потому что это очень предсказуемо.

Для всех других применений более высокая производительность System.Random и эквивалентные классы приветствуются.

2 голосов
/ 24 февраля 2019

В дополнение к предыдущим ответам:

System.Random следует НИКОГДА не использовать в моделированиях или численных решениях для науки и техники, где имеются существенные негативные последствия неточных результатов моделирования или сбоя сходимости. Это связано с тем, что реализация Microsoft является глубоко ошибочной в нескольких отношениях, и они не могут (или не будут) легко ее исправить из-за проблем совместимости. См это сообщение .

Итак:

  • Если есть злоумышленник, который не должен знать сгенерированную последовательность , тогда используйте RNGCryptoServiceProvider или другой тщательно спроектированный, реализованный и проверенный криптографически стойкий ГСЧ, и, по возможности, в идеале используйте аппаратную случайность. В противном случае,

  • Если это приложение, такое как моделирование, которое требует хороших статистических свойств , тогда используйте тщательно разработанный и внедренный не крипто-PRNG, такой как Mersenne Twister . (В этих случаях криптографический ГСЧ также будет правильным , но часто слишком медленным и громоздким.) В противном случае;

  • ONLY , если использование чисел является совершенно тривиальным , например, решение о том, какое изображение показывать следующим в рандомизированном слайд-шоу, затем используйте System.Random.


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

Иногда, когда вы не можете что-то объяснить, за этим стоит причина, и эта причина может быть очень обременительной!

Ниже приведен график значений p , полученных при увеличении количества партий моделирования:

imageSystem.Random">

Красные и пурпурные графики показывают статистическую значимость различий между двумя моделями использования в двух исследуемых выходных метриках.

Голубой график является особенно шокирующим результатом, поскольку он представляет p ‑ значения для характеристики случайного входа для моделирования. (Это было построено только для того, чтобы подтвердить, что входные данные не были ошибочными.) Входные данные, конечно, были одинаковыми для двух исследуемых моделей использования, поэтому не должно было быть статистически значимой разницы между входом на две модели. Тем не менее, здесь я лучше, чем на 99,97%, был уверен, что была такая разница !!

Сначала я думал, что в моем коде что-то не так, но все проверил. (В частности, я подтвердил, что потоки не разделяют System.Random экземпляров.) Когда повторное тестирование показало, что этот неожиданный результат является весьма непротиворечивым, я начал подозревать System.Random.

Я заменил System.Random реализацией Mersenne Twister - никаких других изменений - и сразу же результат стал резко отличаться, как показано здесь:

Input & output _p_‑values after switching to a better PRNG

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

Обратите внимание, что на первом графике вертикальная логарифмическая шкала (в значении p ) охватывает семь десятилетий , тогда как во втором - только одно десятилетие, демонстрирующее только насколько ярко выражена статистическая значимость ложных расхождений! (Вертикальная шкала указывает на вероятность того, что расхождения могли возникнуть случайно.)

Я подозреваю, что System.Random имеет некоторые корреляции относительно довольно короткого поколенияЦикл эратора и различные образцы внутренней случайной выборки между двумя тестируемыми моделями (у которых было существенно различное количество вызовов Random.Next) заставили их по-разному влиять на две модели.

Так получилось, что симуляция вход основана на тех же потоках ГСЧ, что и модели, используемые для внутренних решений, и это, очевидно, привело к тому, что несоответствия выборки повлияли на вход. (Это на самом деле повезло, потому что в противном случае я, возможно, не понял, что неожиданный результат был программной ошибкой, а не каким-то реальным свойством моделируемых устройств!)

...