Насколько Случайный Система. Гуид. NewGuid ()? (Возьмите два),

Прежде чем Вы начнете отмечать это как дубликат, считаете меня. Другой вопрос имеет (наиболее вероятный) неправильный принятый ответ.

Я не знаю, как.NET генерирует свои GUID, вероятно, только Microsoft делает, но существует высокий шанс, который она просто называет CoCreateGuid (). Та функция однако документируется для вызова UuidCreate (). И алгоритмы для создания UUID вполне прилично документируются.

Короче говоря, будьте, как это может, это казаться этим System.Guid.NewGuid() действительно версия 4 использования, алгоритм поколения UUID, потому что все GUID это генерирует, соответствует критериям (лично убеждаются, я попробовал пару миллиона GUID, они все соответствовали).

Другими словами, эти GUID почти случайны, за исключением нескольких известных битов.

Это с другой стороны поднимает вопрос - как случайный действительно ли это случайно? Как каждый хороший маленький программист знает, алгоритм псевдослучайного числа только так же случаен как его семя (иначе энтропия). Таким образом, каково семя для UuidCreate()? Как ofter является пересеянным PRNG? Это криптографически сильно, или я могу ожидать, что те же GUID начнут наливать, если два компьютера случайно будут звонить System.Guid.NewGuid() одновременно? И может состояние PRNG быть предположенным, если достаточно много последовательно сгенерированных GUID собраны?

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

  1. Основная случайность, занимая текущее время в качестве семени. Применимый для перестановки карт в Пасьянсе, но мало еще, поскольку коллизии слишком легки для прибытия даже без попытки.
  2. Более усовершенствованная случайность, с помощью не только время, но и другую машину специфические факторы для семени. Возможно, также отобранный только однажды на системном запуске. Это может использоваться для генерации идентификаторов в DB, потому что дубликаты маловероятны. Однако, это не хорошо для безопасности, потому что результаты могут быть предсказаны с достаточным усилием.
  3. Cryptograhpically случайный, использующий шум устройства или другие усовершенствованные источники случайности для семени. Пересеянный на каждом вызове или по крайней мере симпатичный часто. Может использоваться для идентификаторов сессии, розданных недоверяемым сторонам, и т.д.

Я прибыл в этот вопрос при размышлении, будет ли нормально использовать их в качестве идентификаторов DB, и ли реализация алгоритма Guid.comb вместе с System.Guid.NewGuid() (как NHibernate делает это), был бы испорчен или нет.

43
задан Community 23 May 2017 в 11:54
поделиться

8 ответов

Ответ: вам не нужно этого знать. Как указано в принятом ответе на связанный с вопрос :

GUID не дает гарантий относительно случайности, он дает гарантии относительно уникальности.

Еще более сильное заявление о безопасности и случайности сделано в RFC4122 , в котором конкретизируется формат UUID:

Не думайте, что UUID трудно угадать; они не должны использоваться в качестве средств защиты (например, идентификаторы, простое владение которыми предоставляет доступ). Предсказуемый источник случайных чисел усугубит ситуацию.

Все остальное является деталью реализации (и может быть изменено).

Особенности Windows

Часто люди заявляют, что поведение в Windows задокументировано и, следовательно, гарантируется криптографическая безопасность идентификаторов GUID.

В теперь заархивированном документе [MS-SECO] Обзор безопасности Windows упоминается в Приложении A:

Хотя лишь небольшая часть идентификаторов GUID версии 4 требует криптографической случайности, случайные биты для всех версий 4 GUID, встроенных в Windows, получаются через криптографический API Windows CryptGenRandom или аналогичный, тот же источник, который используется для генерации криптографических ключей.

Более того, в разделе 2.5.5 того же документа явно упоминается использование значений «секретного GUID» в качестве одноразового идентификатора или аутентификатора.

НО: Эта часть документации по поведению продукта не является спецификацией, на которой вы обычно можете основывать безопасность вашего продукта (в частности, в контексте .NET).

Фактически, приведенный выше документ описывает детали реализации конкретного продукта . Даже если текущие реализации Windows и .NET Framework 4.x создают действительно случайные значения UUID версии 4 в Windows, нет никакой гарантии, что System.Guid.NewGuid будет делать это в будущем. или на других платформах .NET (например, Mono, Silverlight, CF, .NET Core и т. д.).

Как пример, алгоритм UUID, используемый в более ранних версиях .NET Core , зависит от платформы , и вы можете получить UUID версии 1 (в BSD).

34
ответ дан 26 November 2019 в 22:58
поделиться

Определение «Случайное» никоим образом не связано с определением «Глобально уникальное».

Дважды подбросить монету и получить HH, HT, TH, TT - все случайным образом. HH так же случайен, как и HT.

Подбросить «особую» монету дважды и гарантировать, что вы получите только HT или TH, - это уникальность.

6
ответ дан 26 November 2019 в 22:58
поделиться

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

Случайность и уникальность - ортогональные концепции.

Случайные данные могут быть уникальными или избыточными, и точно так же уникальные данные могут использовать случайный источник или детерминированный источник (подумайте о глобальном счетчике, который заблокирован и увеличивается на единицу для каждого когда-либо созданного GUID).

GUID были разработаны так, чтобы быть уникальными, а не случайными. Если кажется, что генератор .NET использует случайный ввод, ничего страшного. Но не полагайтесь на него как на источник случайности ни в криптографических, ни в каких-либо других целях (в частности, какую функцию распределения вы ожидаете получить?). С другой стороны, вы можете быть уверены, что GUID, созданные .NET, даже в больших объемах, будут уникальными.

19
ответ дан 26 November 2019 в 22:58
поделиться

Я где-то читал, что шансы выиграть в лотерею будут эквивалентны столкновению двух 4-байтовых "GUID". Стандартные 16-байтовые GUID будут иметь гораздо меньше шансов на столкновение.

-1
ответ дан 26 November 2019 в 22:58
поделиться

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

0
ответ дан 26 November 2019 в 22:58
поделиться

Идентификаторы GUID должны иметь номер 2 в вашей шкале, т.е. «могут использоваться для генерации идентификаторов в БД, поскольку дублирование маловероятно *.»

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

На практике, в соответствии с этим комментарием и этим , генерация GUID реализуется в терминах криптографически безопасного RNG ( CryptGenRandom ). Но это, похоже, недокументированная деталь реализации. (И я это не проверял - это случайные комментарии в Интернете, возьмите с собой тучу соли).

(* Где «маловероятно» означает что-то вроде «шансы любого найти дублированный GUID до конца вселенной меньше, чем шансы лично выиграть в лотерею». За исключением ошибок реализации, конечно.)

1
ответ дан 26 November 2019 в 22:58
поделиться

Сосредоточение внимания на вашем вопросе с использованием GUID в качестве идентификаторов строк :

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

Метод COMB в упомянутой вами статье на самом деле кажется довольно хорошим. Я так и не понял, спасибо за это! ( p.s. версия этой статьи для печати гораздо лучше читается )

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

Также взгляните на Джеффа по ID и GUID

create table #temp ([id] uniqueidentifier primary key default(newid()), [name] varchar(20))
insert into #temp (name) values ('apple')
insert into #temp (name) values ('orange')
insert into #temp (name) values ('banana')
select * from #temp
drop table #temp

id                                   name
------------------------------------ --------------------
911B0CBD-4EED-4EB0-8488-1B2CDD915C02 banana
56CF3A80-A2DE-4949-9C9B-5F890824EA9C orange
5990B9FD-143D-41B0-89D1-957B2C57AB94 apple
0
ответ дан 26 November 2019 в 22:58
поделиться

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

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

public Guid CreateCryptographicallyStrongGuid() {
    var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
    var data = new byte[16];
    rng.GetBytes(data);
    return new Guid(data);
}

Эти идентификаторы GUID представляют собой просто 128 битов криптографической случайности. Они не структурированы и не будут сталкиваться.

См. эту статью для некоторых математических расчетов. Используя «Формулу общего дня рождения», перестановка дает

n = sqrt (-2T * ln (p))

, где n - количество выбранных элементов, T - общее количество элементов (2 ^ 128), а p - целевая вероятность того, что все n выбранных элементов будут разными. При p = 0,99 это дает * n = 2,61532104 * 10 ^ 18 *. Это означает, что мы можем сгенерировать миллиард действительно случайных GUID в секунду в системе в течение миллиарда секунд (32 года), и в конечном итоге с вероятностью более 99% каждый из них будет уникальным в системе.

8
ответ дан 26 November 2019 в 22:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: