2016-07-06 31 views
5

Abbiamo un database SQL esistente con Microsoft Identity tabelle, originariamente generate da un'app di ASP.NET Core.La password (hash) non corrisponde quando si riutilizzano le tabelle utente Microsoft Identity esistenti

Abbiamo anche un'app ASP.NET 4, che utilizza anche Microsoft Identity.

Vorremmo che l'app ASP.NET 4 fosse in grado di verificare gli accessi utilizzando lo stesso database come l'app .NET Core originale.

Tuttavia, quando proviamo a convalidare le password, non corrispondono.

Sto solo supponendo che gli hash delle password generati dall'app .NET Core non possano essere convalidati dall'app ASP.NET 4, ma non sono sicuro di dove andare da qui. :)

Non c'è hashing password personalizzato nell'app .NET Core e sto cercando di trovare config che potrebbero influire sull'hash?

Qualsiasi aiuto o puntatore è molto apprezzato!

Modifica: Sembra che questo possa essere causato da diversi algoritmi di hashing in Identity V2/V3. Non so come imitare l'algoritmo di hashing V3 nell'app ASP.NET 4, però.

risposta

4

Come per la documentazione si trova: https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasher.cs

/* ======================= 
    * HASHED PASSWORD FORMATS 
    * ======================= 
    * 
    * Version 2: 
    * PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit subkey, 1000 iterations. 
    * (See also: SDL crypto guidelines v5.1, Part III) 
    * Format: { 0x00, salt, subkey } 
    * 
    * Version 3: 
    * PBKDF2 with HMAC-SHA256, 128-bit salt, 256-bit subkey, 10000 iterations. 
    * Format: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey } 
    * (All UInt32s are stored big-endian.) 
    */ 

A un certo punto, l'identità utilizzato un algoritmo diverso hashing - forse è utilizzando il formato versione 2 in uno, e il formato versione 3 in un altro?

Il costruttore della classe accetta le opzioni, puoi provare a modificarlo per ottenere l'hash corretto?

public PasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null) 

EDIT:

ho trovato la fonte v2.0 Identity qui: https://aspnetidentity.codeplex.com/ e git repo: https://git01.codeplex.com/aspnetidentity

Sfogliando fonte, ci si imbatte in suo metodo di hashing.

Crypto.HashPassword.cs

public static string HashPassword(string password) 
    { 
     if (password == null) 
     { 
      throw new ArgumentNullException("password"); 
     } 

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

     var 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); 
    } 

Rispetto ai v2 nel nucleo aspnet identità:

private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng) 
    { 
     const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1; // default for Rfc2898DeriveBytes 
     const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes 
     const int Pbkdf2SubkeyLength = 256/8; // 256 bits 
     const int SaltSize = 128/8; // 128 bits 

     // Produce a version 2 (see comment above) text hash. 
     byte[] salt = new byte[SaltSize]; 
     rng.GetBytes(salt); 
     byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength); 

     var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength]; 
     outputBytes[0] = 0x00; // format marker 
     Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize); 
     Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength); 
     return outputBytes; 
    } 

Identity v2 hashing e nucleo dell'identità v2 hashing sembrano abbastanza simili, ora rispetto all'identità nucleo v3 hash :

Non ho intenzione di far finta di capire cosa sta succedendo in t Questi metodi, ma dall'identità v2 e dall'identity core, sono passati da un costruttore senza parametri a uno che accetta le opzioni di configurazione. V2 usa SHA1, V3 usa SHA256 (tra le altre cose).

Sembra che l'identità core di default sia hash utilizzando il metodo V3, che non esisteva nella versione precedente dell'identità, che sarebbe la causa del tuo problema.

https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasherOptions.cs

Nota nell'origine sopra, V3 viene utilizzato come predefinito.

/// <summary> 
    /// Gets or sets the compatibility mode used when hashing passwords. 
    /// </summary> 
    /// <value> 
    /// The compatibility mode used when hashing passwords. 
    /// </value> 
    /// <remarks> 
    /// The default compatibility mode is 'ASP.NET Identity version 3'. 
    /// </remarks> 
    public PasswordHasherCompatibilityMode CompatibilityMode { get; set; } = PasswordHasherCompatibilityMode.IdentityV3; 

Purtroppo, che sembra dire le password che sono state hash nel nucleo identità non può essere lo stesso hash in una versione precedente di identità, come quello vecchio metodo non è stato attuato. Forse potresti creare il tuo imitando ciò che è stato fatto nella v3?

+0

Dispari, la classe PasswordHasher sembra avere solo un costruttore senza parametri. Ma una differenza di versione potrebbe spiegarlo, l'app Core è su Identity 3, mentre l'app ASP.NET 4 è su Identity 2. Non sei sicuro che V3 sia disponibile per .NET 4.6.1? –

+0

Attualmente sto esaminando il porting dell'algoritmo di hash V3 all'app ASP.NET 4. Altrimenti suppongo che l'app Core possa essere cambiata per usare invece l'hashing V2 (fondamentalmente migrando gli hash V3 attuali agli hash V2), ma preferirei davvero rimanere su V3. Grazie mille per il vostro aiuto! –

Problemi correlati