2015-06-04 12 views
5

Ho un progetto in cui è necessario migrare molti utenti che hanno la loro password in testo normale in un nuovo database dove inseriremo la password.Conversione di password normale in EF Asp.Net Identity PasswordHash

Il nuovo sistema utilizza Entity Framework e deve essere autenticato con il framework Asp.Net Identity.

Ho scoperto che posso generare in C# una password hash corretta che Entity Framework può leggere senza problemi.

public static string HashPassword(string password) 
    { 
     byte[] salt; 
     byte[] buffer2; 
     using (var bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8)) 
     { 
      salt = bytes.Salt; 
      buffer2 = bytes.GetBytes(0x20); 
     } 
     byte[] dst = new byte[0x31]; 
     Buffer.BlockCopy(salt, 0, dst, 1, 0x10); 
     Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20); 
     return Convert.ToBase64String(dst); 
    } 

C'è qualcosa di simile in SQL che ho potuto usare all'interno di istruzione INSERT formare una SELECT per l'altra tabella?

+2

non si desidera utilizzare [integrazione CLR SQL Server] (https://msdn.microsoft.com/en-us/library/w2kae45k (v = vs90) .aspx)? – jjj

+0

@jjj Interessante, lasciatemi esplorare questo percorso, non ho mai usato l'integrazione CLR, ma questo potrebbe fare il lavoro –

+0

@jjj Ho fatto un test e ha funzionato. È piuttosto lento da usare, ma credo che ne valga la pena. Per darti un'idea, passa da 7 secondi a 18 minuti :) –

risposta

3

Non incorporato, l'hashing è intensivo di cpu e normalmente un'operazione che si vorrebbe evitare sul server DB, tuttavia mi rendo conto che la migrazione non è un'operazione normale. La soluzione dipende un po 'dal motivo per cui si desidera eseguire in SQL.

Se è a causa della semplicità vorrei guardare qualcosa di simile a questa domanda Is there a SQL implementation of PBKDF2?

Se è a causa di prestazioni vorrei prendere in considerazione solo la costruzione di un piccolo migratore .net e utilizzare rinfusa inserimento/aggiornamento. Ad esempio con https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-update-entities è possibile leggere solo l'ID utente e la password di testo normale con una selezione. Inseriscilo in .net e quindi aggiorna il database in un'unica soluzione, probabilmente con oltre 100.000 aggiornamenti al secondo.

Ora due lievi avvertimenti Assicurati di non finire con password in chiaro nel log delle transazioni. Facilmente eseguendo l'hashing nel database di origine prima che finisca nel nuovo. Altrimenti è possibile cancellare il log delle transazioni dopo l'importazione iniziale How do you clear the SQL Server transaction log?

Invece di scrivere da soli il metodo di hashing, è possibile utilizzare PasswordHasher che è l'identità di Asp.net utilizzata per impostazione predefinita. A sua volta sta usando Rfc2898DeriveBytes. Vedere questa risposta https://stackoverflow.com/a/21496255/507279

+0

Grazie per la risposta. Darò sicuramente un'occhiata più da vicino al tuo approccio. Voglio eseguire in SQL perché sto creando un'enorme conversione DB con LinkedServer. Ho questo vecchio tavolo che ha bisogno di entrare in uno nuovo che ha bisogno della password per essere hash. È l'unica tabella che richiede davvero una strana manipolazione finora. Cerco di evitare di avere troppo. Netto codice perché questo è un progetto di 1 volta. Una volta completata la conversione, non avremo più bisogno del progetto. –

+0

Buon punto sul TLOG. OP sta già utilizzando [Rfc2898DeriveBytes] (https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396), anche se a solo 1000 iterazioni che [non è sufficiente secondo OWASP] (http://stackoverflow.com/a/14263775/314291) - questo dovrebbe essere più di 100k ormai. Tuttavia notate che, per impostazione, tutte queste iterazioni rendono l'hashing lento (100ms #hash), il che significa che ci vorrà molto tempo prima che voi migriate un gran numero di password. – StuartLC

+0

@PatrickDesjardins Ci vorrebbe <50 LOC di C# anche se si vuole parallelizzarlo (vedi commento Stuart). Stai facendo una migrazione "calda" o la manterrai offline durante la migrazione? Se stai facendo una migrazione a caldo. Potrebbe essere necessario preparare gli hash prima della mano comunque. –