2010-04-17 18 views
56

Qual è la differenza tra l'utilizzo di Rfc2898DeriveBytes e l'utilizzo di Encoding.ASCII.GetBytes(string object);?Perché è necessario utilizzare la classe Rfc2898DeriveBytes (in .NET) anziché utilizzare direttamente la password come chiave o IV?

Ho avuto un successo relativo con entrambi gli approcci, il primo è un approccio più lungo e tortuoso in cui quest'ultimo è semplice e preciso. Entrambi sembrano permetterti di fare la stessa cosa alla fine, ma mi sto sforzando di vedere il punto in cui usare la prima su quest'ultima.

Il concetto di base sono stato in grado di cogliere è che è possibile convertire le password stringa in array di byte da utilizzare per es una classe crittografia simmetrica, AesManaged. Tramite la classe RFC, ma è possibile utilizzare i valori salt e la password durante la creazione dell'oggetto rfc. Presumo che sia più sicuro, ma comunque è un'ipotesi non istruita al meglio! Inoltre, ti permette di restituire array di byte di una certa dimensione, anche qualcosa del genere.

Ecco alcuni esempi per mostrare dove vengo da:

byte[] myPassinBytes = Encoding.ASCII.GetBytes("some password"); 

o

string password = "[email protected]%5w0r]>"; 
byte[] saltArray = Encoding.ASCII.GetBytes("this is my salt"); 
Rfc2898DeriveBytes rfcKey = new Rfc2898DeriveBytes(password, saltArray); 

L'oggetto 'rfcKey' possono ora essere utilizzati verso la creazione della del .Key o Proprietà .IV in una classe di algoritmo di crittografia simmetrica.

ie.

RijndaelManaged rj = new RijndaelManaged(); 
rj.Key = rfcKey.Getbytes(rj.KeySize/8); 
rj.IV = rfcKey.Getbytes(rj.Blocksize/8); 

'rj' dovrebbe essere pronto per andare!

La parte confusa ... quindi piuttosto che utilizzare l'oggetto 'rfcKey' non posso semplicemente usare la mia matrice 'myPassInBytes' per aiutare a configurare il mio oggetto 'rj'?

Ho provato a farlo in VS2008 e la risposta immediata è NO. Ma voi ragazzi avete una risposta più istruita sul motivo per cui la classe RFC viene utilizzata rispetto all'altra alternativa che ho menzionato sopra?

+0

Questa domanda è in relazione alla revisione e preparazione per l'esame! – IbrarMumtaz

risposta

135

Si davvero, davvero non si vuole usare una password utente direttamente come chiave crittografica, in particolare con AES.

Rfc2898DeriveBytes è un'implementazione di PBKDF2. Quello che fa è ripetutamente cancellato la password dell'utente insieme al sale. Questo ha molteplici vantaggi:

In primo luogo, è possibile utilizzare password di dimensioni arbitrarie - AES supporta solo dimensioni chiave specifiche.

In secondo luogo, l'aggiunta di sale indica che è possibile utilizzare la stessa passphrase per generare più chiavi diverse (presupponendo che il sale non sia una costante, come nel proprio esempio). Questo è importante per la separazione delle chiavi; riutilizzare le chiavi in ​​diversi contesti è uno dei modi più comuni in cui i sistemi di crittografia vengono interrotti.

Le ripetizioni multiple (1000 per impostazione predefinita) rallentano gli attacchi di individuazione della password. Considera qualcuno che sta cercando di indovinare la tua chiave AES. Se hai appena usato la password, sarebbe semplice: basta provare ogni password possibile come chiave. D'altra parte, con PBKDF2, l'utente malintenzionato deve prima eseguire 1000 iterazioni di hash per ciascuna ipotesi di password. Quindi mentre rallenta leggermente un utente, ha un effetto sproporzionato su un utente malintenzionato. (In realtà è abbastanza comune usare conteggi di iterazione molto più alti, generalmente si consiglia 10000).

Significa anche che la chiave di uscita finale è distribuita uniformemente. Se hai usato la password, ad esempio, in genere 16 su 128 bit della chiave sarebbero 0 (il bit ASCII alto). Questo proprio lì rende immediatamente la ricerca delle chiavi 65536 volte più semplice di quanto dovrebbe essere, ignorando anche la possibilità di indovinare la password.

Infine, AES presenta vulnerabilità specifiche con attacchi chiave correlati. Gli attacchi chiave correlati sono possibili quando un utente malintenzionato conosce alcuni dati crittografati con più chiavi e vi è una relazione nota (o indovinata) tra di loro. Ad esempio, se hai crittografato i dati con una chiave di accesso "My AES key sucks" (16 byte, per AES-128) e con "MY AES KEY SUCKS", potrebbe essere possibile un attacco chiave correlato. Gli attacchi attualmente più noti non consentono in realtà di rompere l'AES completo in questo modo, ma sono migliorati progressivamente nel tempo - solo la scorsa settimana è stato pubblicato un nuovo attacco che interrompe 13 round (su 14 totali) di AES-256 usando un attacco chiave correlato. Sarebbe profondamente imprudente fare affidamento su tali attacchi non migliorando nel tempo.

+2

wow grazie per questo, buona risposta. – IbrarMumtaz

+0

ottima risposta - thx! –

+0

Questa risposta è stata molto utile. Ho imparato qualcosa di nuovo oggi. Grazie. –

4

Risposta breve: è più sicuro. Per lo stesso motivo esiste anche un generatore casuale speciale nello spazio dei nomi System.Security.

Per ulteriori informazioni, vedere RFC2898

ho capito una piccola parte:

con Encoding.ASCII.GetBytes(), quando si utilizza una password lunga, si utilizzerà al massimo i primi byte rj.KeySize di esso. Il resto è ignorato. E quando la tua password è più corta della keysize dovrai aggiungere padding (e solo aggiungere una sequenza di 0 aumenta la vulnerabilità).

+0

ahhh questo ha senso, quando usiamo l'oggetto rfc, arriviamo a specificare la dimensione dell'array di byte da restituire. Per assicurarsi che stiamo incontrando la proprietà della dimensione della chiave degli algoritmi. – IbrarMumtaz