2013-07-17 7 views
21

In passato, quando ho a che fare con le password, ho sempre archiviato una password salt e una hash separatamente nel mio archivio dati. Oggi stavo cercando di aggiornare alcuni codici legacy per utilizzare un valore hash RFC 2898. Ho trovato i metodi Crypto.Hash da System.Web.Helpers. Sembra che questi faranno la maggior parte del sollevamento per me. Esistono i metodi GenerateSalt(), HashPassword() e VerifyHashedPassword(). I metodi e VerifyHashedPassword() non prendono un valore salt. La documentazione MSDN per il metodo dice:System.Web.Helpers.Crypto - Dov'è il sale?

"Il formato del toastest dell'hash generato è {0x00, salt, subkey}, che è codificato in base 64 prima di essere restituito."

Devo preoccuparmi di un sale? La documentazione sembra dire che un sale verrà generato automaticamente e memorizzato nel valore codificato in base 64? È corretto? Tutto quello che devo memorizzare è la stringa restituita da HashPassword()?

risposta

42

risposta

Tutte le password devono essere salato, al fine di hash in modo sicuro. In questo caso, tuttavia, sei corretto. System.Web.Helpers.Crypto si occupa di creare un sale per te. non è necessario crearne uno. È memorizzato nella stringa restituita da Crypto.HashPassword().

Esempio

Tutto ciò che devi fare è qualcosa di simile.

using System.Web.Helpers; 

public void SavePassword(string unhashedPassword) 
{ 
    string hashedPassword = Crypto.HashPassword(unhashedPassword); 
    //Save hashedPassword somewhere that you can retrieve it again. 
    //Don't save unhashedPassword! Just let it go. 
} 

public bool CheckPassword(string unhashedPassword) 
{ 
    string savedHashedPassword = //get hashedPassword from where you saved it 

    return Crypto.VerifyHashedPassword(savedHashedPassword, unhashedPassword) 
} 

Ulteriori informazioni

  • Se volete vedere il codice sorgente per la classe Crypto è possibile visualizzarlo here.
  • E here è un buon blog sulla classe e alcune delle idee alla base.
+0

+1 ma dov'è il post sul blog –

+0

non riesco a immaginare come si crea un sale, ma non si memorizza nel database per la prossima verifica ? –

+5

@LeandroDeMelloFagundes La password salt e Hashed sono entrambe memorizzate nella stringa singola restituita da 'Crypto.HashPassword' –

0

Volevo solo condividere questo post:

http://forums.asp.net/t/1842429.aspx?System+Web+Helpers+Crypto+HashPassword

Ciao,
Sono stato a guardare il nuovo metodo Crypto HashPassword e VerifyMethod in System.Web.Helpers.
Entrambi i metodi usano un sale ma non restituiscono il sale solo l'hash.
Non ho bisogno del sale per memorizzarlo nel database? Mi sto perdendo qualcosa?
Grazie,
Miguel

..

Faresti generare il sale quando l'utente crea l'account, e poi si sarebbe aggiungerlo alla password prima di chiamare HashPassword . Avresti quindi memorizza quella salt e la password hash nel tuo DB. Quando si convalidano le credenziali , basta leggere il sale dal DB e aggiungerlo a la password dal login prima di chiamare VerifyHashedPassword. BrockAllen

..

Non sono sicuro se ho capito ... Perché in HashPassword un sale è generato all'interno del metodo:

Miguel

// Method in Crypto class 
public static string HashPassword(string password) 
{ 
    if (password == null) 
    { 
     throw new ArgumentNullException("password"); 
    } 

    // Produce a version 0 (see comment above) password hash. 
    byte[] salt; 
    byte[] subkey; 
    using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount)) 
    { 
     salt = deriveBytes.Salt; 
     subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength); 
    } 

    byte[] outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength]; 
    Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize); 
    Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength); 
    return Convert.ToBase64String(outputBytes); 
} 

..

BrockAllen 11 Settembre 2012 19:50

Sì, ignorare che - è un sale interno per i Rfc2898DeriveBytes ed è derivata dalla password in modo che non è un vero e sale in il contesto di memorizzare le password poiché è costantemente ricreato per la stessa password. Si vorrà comunque eseguire il proprio sale con il livello di stringa password . Quindi, qualcosa di simile:

public void CreateAccount(string username, string password) 
{ 
    var salt = Crypto.GenerateSalt(); 
    var saltedPassword = password + salt; 
    var hashedPassword = Crypto.HashPassword(saltedPassword); 
    CreateAccount(username, salt, hashedPassword); 
} 

public void Verify(string username, string password) 
{ 
    var salt = GetSaltForUserFromDatabase(username); 
    var hashedPassword = GetHashedPasswordForUserFromDatabase(username); 
    var saltedPassword = password + salt; 
    if (Crypto.VerifyHashedPassword(hashedPassword, saltedPassword)) 
    { 
     // valid password for this username 
    } 
} 

Questo vi permetterà di memorizzare il vostro sale nel database insieme alla password hash salata.

Ulteriori informazioni password hashing con sale, in generale, da questo post: https://crackstation.net/hashing-security.htm

per memorizzare una password

  1. Generare una lunga sale casuale usando un CSPRNG.
  2. Premere il tasto Salt sulla password e cancellarlo con una funzione di hash crittografica standard come SHA256.
  3. Salva sia il sale che l'hash nel record del database dell'utente.

per convalidare una password

  1. Recuperare sale dell'utente e hash dal database.
  2. Prependete il sale alla password specificata e cancellatelo usando la stessa funzione di hash.
  3. Confrontare l'hash della password fornita con l'hash dal database. Se corrispondono, la password è corretta. Altrimenti, la password non è corretta.

codice sorgente per la classe Crypto:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs

+2

Questa risposta è fuorviante e obsoleta. Non è necessario creare manualmente il proprio sale. Brock Allen non era corretto sulla necessità di farlo e ha aggiornato il thread in seguito con questo commento: BrockAllen "Non è necessario inserire manualmente la password, operazione già eseguita dall'API Crypto.HashPassword. Vedere questo post: http://brockallen.com/2012/10/19/password-management-made-easy-in-asp-net-with-the-crypto-api/ – NickG

Problemi correlati