Безпечно генеруйте 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
Mr.Mindor

1
Ви розумієте, що єдиним визначальним фактором рівня вашої безпеки є бітова ентропія? Ідея про те, що NEWID недостатньо випадкова для ваших потреб, означатиме, що ви маєте деяке уявлення про кількість бітової ентропії, яку потрібно "захистити" для вашого випадку використання. Яке це число?
Кейд Ру

2
@usr - "даючи повне знання про внутрішній стан", можна зламати будь-який підхід.

Відповіді:


26
SELECT CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER)

Слід зробити трюк, який я міг би подумати.

CRYPT_GEN_RANDOM

Повертає криптографічне випадкове число, сформоване API Crypto API (CAPI).


4

Всього два мої центи, але це може бути не гарною ідеєю. Якщо перефразовувати чудову серію Еріка Ліпперта щодо GUID ( частина 1 , частина 2 , частина 3 ), абревіатура є GUID, а не GSUID - глобально унікальний ідентифікатор, а не глобально безпечний унікальний ідентифікатор.

Проблема полягає в тому, що коли GUID генеруються в неприязні області, такі як усі, хто використовує NEWID (), всі значення гарантуються як унікальні (ну, див. Статтю Еріка, частина 3). Але якщо вороже сутність входить у цю область, вони можуть як передбачити наступний створений GUID, так і самостійно спричинити зіткнення.

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

Я кажу, що це може бути не дуже хорошою ідеєю лише тому, що я не знаю всієї сфери використання цих значень. Якщо ви єдиний суб'єкт, який генерує значення (без змішування та збігу), та / або ви не зберігаєте значення та / або вам не байдуже зіткнення, це може не бути проблемою. Якщо будь-який із цих пунктів не відповідає дійсності, ви можете повторно оцінити.


Цікаві моменти. Вибір мого типу даних UNIQUEIDENTIFIER- це здебільшого збіг. Це просто зручно обробляти 16-байтну кількість за допомогою цього типу. Я вважаю це паролем. Але це повинно бути унікальним. Я впевнений, що зіткнення ніколи не побачу (і навіть якщо там додаток просто вийде з ладу - тож це теж безпечно).
usr

Я не погоджуюся, це залежить від того, як ви зашифруєте це, якщо воно стане випадковим, а не унікальним. Це легко може бути однаковим.
Dawesi

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. Зниження криптографічної випадковості GUID в деяких майбутніх версіях Windows було б вкрай малоймовірним. Не було би чого отримати.
Йордан Рігер

Ця сторінка MSDN просто документує історичний вибір, але не говорить про те, що це буде зберігатися і надалі. Те саме для SQL Server. Я не можу уявити обставин, за яких це може зламатися. Але трапилося багато катастрофічних дебалел РНГ. Припущення на кшталт цього часто виявлялися помилковими. Це евристичний аргумент.
usr

@usr Але як будь-яка документація MSDN може гарантувати подальшу поведінку Windows? Найбільше, на що ми можемо сподіватися у цих випадках, - це документація поточної поведінки. Якщо поведінка колись змінюється, тоді вони оновлюють документацію. Ось чому ці переповнення стека Q & As мають теги версій і періодично оновлюються.
Йордан Рігер

Вони дійсно дають гарантії щодо речей, які вони не змінять. Вони можуть змінити продукт, але цього не зроблять, якщо скажуть "ось важлива функція безпеки з цими властивостями". Я трактую цю документацію як швидше історичний погляд, ніж твердження про майбутнє.
usr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.