2016-05-11 21 views
13

Desidero creare un GUID crittografico (v4) in .NET.Creare un GUID casuale protetto da crittografia in .NET

La funzione .NET Guid.NewGuid() non è protetta da crittografia, ma .NET fornisce la classe System.Security.Cryptography.RNGCryptoServiceProvider.

Mi piacerebbe essere in grado di passare una funzione di numero casuale come delegato a Guid.NewGuid (o anche passare una classe che fornisce un'interfaccia generatore) ma non sembra possibile con l'implementazione predefinita.

Posso creare un GUID crittograficamente sicuro utilizzando System.GUID e System.Security.Cryptography.RNGCryptoServiceProvider insieme?

+0

Qualsiasi motivo per il voto ravvicinato drive-by? Commenti e feedback sono sempre apprezzati, per quanto rari possano essere su SO. –

risposta

21

Sì, è possibile, Guid consente di creare un GUID utilizzando un array di byte, e RNGCryptoServiceProvider in grado di generare un array di byte a caso, in modo da poter utilizzare l'uscita per alimentare un nuovo GUID:

public Guid CreateCryptographicallySecureGuid() 
{ 
    using (var provider = new RNGCryptoServiceProvider()) 
    { 
     var bytes = new byte[16]; 
     provider.GetBytes(bytes); 

     return new Guid(bytes); 
    } 
} 
+0

Aspetta, è davvero così semplice? Pensavo che esistesse uno standard GUID - i primi pochi non definiscono la versione utilizzata, mentre gli ultimi pochi definiscono qualcos'altro? Pensavo che ci fosse più di un GUID che di byte casuali, da qui la domanda. –

+1

C'è una differenza tra un GUID crittograficamente sicuro e una guida standardizzata, se si desidera che la guida eviti la collisione, quindi utilizzare Guid.NewGuid, altrimenti utilizzare questa. Qualsiasi guida standardizzata non sarà crittograficamente sicura in quanto vi sono regole per generarli come hai detto correttamente, quindi la sua forza sarebbe molto bassa (se sai come vengono generati 8 dei 16 byte, devi solo rinforzarli con questi 8 byte .. .) – Gusman

+0

Non ci avevo pensato. Lo sto utilizzando per le e-mail di attivazione: genera un GUID per un URL di attivazione dell'account. Questi sarebbero archiviati nel DB, quindi idealmente non dovrebbero collidere e idealmente dovrebbero essere crittograficamente sicuri (molto difficili da indovinare). Mi stavo chiedendo se ci fosse un buon modo per ottenere entrambi. (Per scopi pratici posso probabilmente usare un GUID o 'Cryptography.getHash', ma se c'è un modo per fare le cose correttamente, questa è l'opzione che prenderò.) –

11

Se qualcuno è interessato qui è il codice di esempio sopra corretto per .NET Core 1.0 (DNX)

public Guid CreateCryptographicallySecureGuid() 
{ 
    using (var provider = System.Security.Cryptography.RandomNumberGenerator.Create()) 
    { 
     var bytes = new byte[16]; 
     provider.GetBytes(bytes); 

     return new Guid(bytes); 
    } 
}