Безопасно сгенерируйте UNIQUEIDENTIFIER в SQL Server


15

Я намерен использовать UNIQUEIDENTIFIERв качестве ключа доступа, который пользователи могут использовать для доступа к определенным данным. Ключ будет действовать как пароль в этом смысле.

Мне нужно сгенерировать несколько таких идентификаторов как часть INSERT...SELECTзаявления. По архитектурным соображениям я хочу генерировать идентификаторы на стороне сервера в этом случае.

Как я могу создать надежно случайный UNIQUEIDENTIFIER? Обратите внимание, что NEWIDэто не было бы достаточно случайным, поскольку это не обещает никаких свойств безопасности вообще. Я ищу SQL Server эквивалент System.Security.Cryptography.RandomNumberGenerator, потому что мне нужны неосуществимые идентификаторы. Все, что основано CHECKSUM, RANDили не GETUTCDATEбудет соответствовать требованиям.


2
@AaronBertrand по крайней мере, один, если цифры всегда 4. Но тот факт, что у меня нет убедительных доказательств того, что они могут быть угаданными, не означает, что это не так. Я не могу основать это решение по безопасности на этом наблюдении.
USR

1
Возможно, NEWID такой же случайный, как и «слабые ключи SSH Debian»: en.wikinews.org/wiki/… Они, безусловно, выглядели случайными для разработчика, который их тестировал ...
usr

2
Это 4 говорит вам, какой алгоритм используется при генерации GUID. en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
Мистер Миндор,

1
Вы понимаете, что единственным определяющим фактором уровня вашей безопасности является битовая энтропия? Идея о том, что NEWID недостаточно случайна для ваших нужд, подразумевает, что у вас есть представление о количестве битовой энтропии, которое требуется, чтобы быть «безопасным» для вашего варианта использования. Что это за номер?
Cade Roux

2
@usr - «при полном знании внутреннего состояния» можно взломать любой подход.

Ответы:


26
SELECT CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER)

Должен сделать трюк, я бы подумал.

CRYPT_GEN_RANDOM

Возвращает криптографическое случайное число, сгенерированное Crypto API (CAPI).


4

Просто мои два цента, но это может быть не очень хорошая идея. Перефразируя превосходную серию Эрика Липперта о GUID ( часть 1 , часть 2 , часть 3 ), аббревиатура - GUID, а не GSUID - глобальный уникальный идентификатор, а не глобальный безопасный уникальный идентификатор.

Проблема заключается в том, что когда GUID генерируются в не враждебной области, такой как каждый, использующий NEWID (), гарантируется, что все значения будут уникальными (ну, вроде как, см. Статью Эрика, часть 3). Но если вражеский объект входит в эту область, они могут как предсказать следующий сгенерированный GUID, так и вызвать конфликты самостоятельно.

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

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


Интересные моменты. Мой выбор типа данных UNIQUEIDENTIFIERв основном совпадение. С этим типом просто удобно обрабатывать 16-байтовое количество. Я думаю об этом как пароль. Это должно быть уникальным, хотя. Я уверен, что никогда не увижу столкновения (и даже если приложение будет просто зависать - это тоже безопасно).
USR

Я не согласен, это зависит от того, «как» вы его зашифруете, если оно станет случайным, а не уникальным. Это может легко быть тем же самым.
Давеси

4

Согласно https://blogs.msdn.microsoft.com/sqlprogrammability/2006/03/23/newsequentialid-histrorybenefits-and-implementation/ , функция NEWID () просто оборачивает функцию Windows CoCreateGuid, которая возвращает GUID в стиле v4 , И согласно https://msdn.microsoft.com/en-us/library/bb417a2c-7a58-404f-84dd-6b494ecf0d13#id11 , начиная с Windows 2000 еще в 1999 году,

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

Поэтому я бы сказал, что вы можете считать NEWID () криптографически безопасным - по крайней мере, в той степени, в которой он обеспечивает 122 бита энтропии.


Это интересно. Я лично не доверял бы этому в целях безопасности. Ни Windows, ни SQL Server не гарантируют этого.
USR

@usr Я не уверен, как будет выглядеть гарантия. Он не использует слово «гарантия», но представляется стандартной документацией MSDN для Windows SDK. Для MS было бы крайне маловероятно понизить криптографическую случайность GUID в некоторых будущих версиях Windows. Там было бы нечего получить.
Джордан Ригер

Эта страница MSDN просто документирует исторический выбор, но не говорит, что это будет сохранено в будущем. То же самое для SQL Server. Я не могу представить обстоятельства, при которых это сломалось бы. Но было много катастрофических неудач ГСЧ. Подобные предположения часто оказывались ложными. Это эвристический аргумент.
USR

@usr Но как любая документация MSDN может гарантировать дальнейшее поведение Windows? Максимум, на что мы можем надеяться в этих случаях, это документирование текущего поведения. Если поведение когда-либо изменится, тогда они обновят документацию. Вот почему эти вопросы и ответы по Stack Overflow имеют теги версий и время от времени обновляются.
Джордан Ригер

Они дают гарантии о вещах, которые они не изменят. Они могут изменить продукт, но не сделают этого, если скажут: «Вот критическая функция безопасности с этими свойствами». Я интерпретирую эту документацию скорее как исторический взгляд, чем как заявление о будущем.
USR
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.