Generare in modo sicuro un UNIQUEIDENTIFIER in SQL Server


15

Intendo utilizzare una UNIQUEIDENTIFIERchiave di accesso che gli utenti possono utilizzare per accedere a determinati dati. La chiave fungerà da password in questo senso.

Devo generare più identificatori come parte di una INSERT...SELECTdichiarazione. Per motivi di architettura, in questo caso desidero generare gli identificatori lato server.

Come posso generare un casuale in modo sicuro UNIQUEIDENTIFIER? Si noti che NEWIDnon sarebbe abbastanza casuale in quanto non promette alcuna proprietà di sicurezza. Sto cercando l'equivalente di SQL Server di System.Security.Cryptography.RandomNumberGenerator perché ho bisogno di ID non indovinabili. Qualsiasi cosa basata su CHECKSUM, RANDo GETUTCDATEanche non si qualificherebbe.


2
Almeno @AaronBertrand, uno se le cifre sono sempre 4. Ma il fatto che non ho prove evidenti che potrebbero essere ipotizzabili non significa che non lo siano. Non posso basare questa decisione sulla sicurezza su questa osservazione.
usr

1
Forse NEWID è casuale come le "chiavi SSH Debian deboli": en.wikinews.org/wiki/… Hanno sicuramente avuto un aspetto casuale per lo sviluppatore che le ha testate ...
usr

2
Quel 4 ti dice quale algoritmo viene utilizzato nella generazione del GUID. en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
Mr.Mindor

1
Capisci che l'unico fattore determinante nel livello di sicurezza è l'entropia dei bit? L'idea che NEWID non sia abbastanza casuale per le tue esigenze implicherebbe che tu abbia qualche idea della quantità di bit entropia che deve essere "sicura" per il tuo caso d'uso. Qual è quel numero?
Cade Roux,

2
@usr - "data la piena conoscenza dello stato interno", si può infrangere qualsiasi approccio.

Risposte:


26
SELECT CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER)

Dovrei fare il trucco che avrei pensato.

CRYPT_GEN_RANDOM

Restituisce un numero casuale crittografico generato dall'API Crypto (CAPI).


4

Solo i miei due centesimi, ma questa potrebbe non essere una buona idea. Per parafrasare l'eccellente serie di Eric Lippert su GUID ( parte 1 , parte 2 , parte 3 ), l'acronimo è GUID, non GSUID - Identificatore univoco globale, non Identificatore univoco globale sicuro.

Il problema sta nel fatto che quando i GUID sono generati in un ambito non ostile, come tutti quelli che usano NEWID (), tutti i valori sono garantiti come unici (beh, vedi l'articolo di Eric, parte 3). Ma se un'entità ostile entra in tale ambito, può sia prevedere il GUID generato successivo, sia causare collisioni da solo.

Creando il tuo metodo per generare un valore che memorizzi all'interno di una struttura che assomiglia a un GUID, sei essenzialmente diventato un'entità ostile. Hai cambiato il contratto di un GUID da unico a casuale . Mentre qualcuno in matematica più bravo di quanto io possa probabilmente dimostrare che sei ancora unico, questo è solo all'interno dei confini del tuo metodo di generazione. Se mescoli questi pseudo-GUID con i GUID NEWID (), tutte le scommesse sono disattivate.

Dico che questa potrebbe non essere una buona idea solo perché non conosco l'intero scopo di come stai usando i valori. Se sei l'unica entità che genera i valori (nessun mix and match) e / o non stai persistendo i valori e / o non ti preoccupi delle collisioni, questo potrebbe non essere un problema. Se qualcuno di questi elementi non è vero, potresti voler rivalutare.


Punti interessanti. La mia scelta del tipo di dati UNIQUEIDENTIFIERè principalmente una coincidenza. È solo conveniente gestire una quantità di 16 byte usando quel tipo. Lo considero una password. Deve essere unico, però. Sono sicuro che non vedrò mai una collisione (e anche se c'è l'app si bloccherà, quindi è sicuro).
usr

Non sono d'accordo, dipende da "come" crittografarlo se diventa casuale piuttosto che unico. Può essere facilmente lo stesso.
Dawesi,

4

Secondo https://blogs.msdn.microsoft.com/sqlprogrammability/2006/03/23/newsequentialid-histrorybenefits-and-implementation/ , la funzione NEWID () avvolge semplicemente la funzione Windows CoCreateGuid, che restituisce un GUID in stile v4 . E secondo https://msdn.microsoft.com/en-us/library/bb417a2c-7a58-404f-84dd-6b494ecf0d13#id11 , poiché Windows 2000 risale al 1999,

"i bit casuali per tutti i GUID versione 4 creati in Windows sono ottenuti tramite l'API crittografica Windows CryptGenRandom o l'equivalente, la stessa fonte utilizzata per la generazione di chiavi crittografiche"

Quindi direi che potresti considerare NEWID () crittograficamente sicuro - almeno nella misura dei 122 bit di entropia che fornisce.


Interessante. Personalmente non mi fiderei di questo per motivi di sicurezza. Né Windows né SQL Server offrono una garanzia in merito.
usr

@usr Non sono sicuro di come sarebbe una garanzia. Non utilizza la parola "garanzia", ​​ma sembra essere la documentazione standard MSDN Windows SDK. Sarebbe estremamente improbabile che MS declassasse la casualità crittografica dei GUID in alcune versioni future di Windows. Non ci sarebbe nulla da guadagnare.
Jordan Rieger,

Quella pagina MSDN documenta semplicemente scelte storiche ma non dice che questo sarà conservato in futuro. Lo stesso per SQL Server. Non riesco a immaginare circostanze in cui ciò si guasterebbe. Ma ci sono stati molti disastri catastrofici di RNG. Ipotesi come questa si sono spesso rivelate false. È un argomento euristico.
usr

@usr Ma come può la documentazione MSDN garantire il comportamento futuro di Windows? Il massimo che possiamo mai sperare in questi casi è la documentazione del comportamento attuale. Se il comportamento cambia, beh, allora aggiornano la documentazione. Ecco perché queste domande e risposte di Stack Overflow hanno tag di versione e vengono periodicamente aggiornate.
Jordan Rieger,

Garantiscono cose che non cambieranno. Potrebbero cambiare il prodotto ma non lo faranno se dicono "ecco una funzione critica per la sicurezza con queste proprietà". Interpreto quella documentazione in questione più come una visione storica che una dichiarazione sul futuro.
usr
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.