2009-08-12 11 views
20

In che modo l'appartenenza ASP.NET genera la propria chiave salina e quindi come la codificano (ovvero, sale + password o password + sale)?sale adesione ASP.NET?

Sto usando SHA-1 con la mia appartenenza, ma vorrei ricreare gli stessi sali in modo che la roba di appartenenza incorporata potesse eseguire lo hash delle cose nello stesso modo in cui le mie cose possono.

Modifica 2: Non importa. Ho letto male e pensavo che dicesse byte, non bit. Quindi stavo passando 128 byte, non 128 bit.

Modifica: Ho cercato di renderlo tale. Questo è quello che ho,

public string EncodePassword(string password, string salt) 
{ 
    byte[] bytes = Encoding.Unicode.GetBytes(password); 
    byte[] src = Encoding.Unicode.GetBytes(salt); 
    byte[] dst = new byte[src.Length + bytes.Length]; 

    Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 

    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 

    byte[] inArray = algorithm.ComputeHash(dst); 

    return Convert.ToBase64String(inArray); 
} 

private byte[] createSalt(byte[] saltSize) 
{ 
    byte[] saltBytes = saltSize; 

    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); 
    rng.GetNonZeroBytes(saltBytes); 

    return saltBytes; 
} 

così non ho provato a vedere se l'appartenenza ASP.NET riconoscerà questo ancora l'hash della password sembra vicino. Solo non so come convertirlo in base64 per il sale.

ho fatto questo

byte[] storeSalt = createSalt(new byte[128]); 
string salt = Encoding.Unicode.GetString(storeSalt); 
string base64Salt = Convert.ToBase64String(storeSalt); 

int test = base64Salt.Length; 

lunghezza Test è 172, che è ben sopra i 128 bit in modo che quello che sto facendo di sbagliato?

Questo è ciò che si rispetti sembra

vkNj4EvbEPbk1HHW+K8y/A== 

Questo è ciò che il mio sale sembra

E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI= 
+0

È possibile controllare la mia risposta su questo SO pagina: http://stackoverflow.com/questions/530426/reimplement-asp-net-membership-and- user-password-hashing-in-ruby/8184569 # 8184569 –

risposta

18

What is default hash algorithm that ASP.NET membership uses? ha una buona discussione del loro algoritmo predefinito.

Spero che questo aiuti!

Modifica- La risposta mi riferivo è il codice nel post alto,

public string EncodePassword(string pass, string salt) 
    { 
     byte[] bytes = Encoding.Unicode.GetBytes(pass); 
     //byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013 
     byte[] src = Convert.FromBase64String(salt); 
     byte[] dst = new byte[src.Length + bytes.Length]; 
     Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
     Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
     HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
     byte[] inArray = algorithm.ComputeHash(dst); 
     return Convert.ToBase64String(inArray); 
    } 

Essi stanno combinando Unicode Salt + Passo utilizzando BlockCopy

- In risposta alla tua domanda:

Entrambi gli algoritmi sono necessarie e svolgono ruoli diversi ...

RNG Crypto viene utilizzato per generare il sale. È fondamentalmente una lunga serie di dati casuali. Questo viene generato e memorizzato in base all'utente. In genere ciò viene eseguito quando viene creato un utente o viene modificata una password.

BlockCopy è solo il metodo che usano per combinare il sale con la password. Il codice sopra equivale essenzialmente a salt + password.

Non è possibile ricreare un valore di sale poiché è completamente casuale. È, tuttavia, memorizzato per ogni utente dal framework.

Combinando il sale con la password e eseguendo l'hash con la tecnica precedente, è possibile verificare le password degli utenti utilizzando il valore hash memorizzato dal framework.

Penso che entrambi abbiamo letto la tua domanda in modo diverso.Il codice che ho postato non genererà il tuo sale, ma ti permetterà di usarlo in un modo compatibile con l'appartenenza ad ASP.NET.

Scusa, la mia spiegazione non è la migliore: risponde alla tua domanda?

+0

Non ti dice come fa Microsoft Salt. –

+0

Il post superiore mostra l'algoritmo: l'ho copiato qui per chiarezza. –

+0

Scusa- capisco cosa intendi. Immaginavo che stesse cercando come si combinasse per ricreare dai dati esistenti. –

1

Ecco un modo per farlo. Un sale è solo un numero a caso, è possibile utilizzare la classe RNGCryptoServiceProvider nella biblioteca quadro di produrre buon numero casuale da utilizzare come sale

private const int ITERATIONS = 10000; 
private const int SALT_SIZE = 32; 
private const int HASH_SIZE = 32; 

public void SaltAndHashPassword(string password, out byte[] salt, 
    out byte[] hash) 
{ 
    Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(
    password, 
    SALT_SIZE, 
    ITERATIONS); 

    salt = rdb.Salt; 
    hash = rdb.GetBytes(HASH_SIZE); 
} 
+0

Hi ho trovato su msdn questa "PasswordSalt: generato casualmente valore 128 bit utilizzato per sale hash delle password; memorizzato in forma di base-64-encoded" http://msdn.microsoft.com/en-us/library /aa478949.aspx Quindi cosa potrei fare su salt_size a 128? che ne dici di dimensioni hash? – chobo2

+0

hanno anche questo MembershipPasswordFormat.Hashed (il valore predefinito), che memorizza gli hash salati generati da password e risposte alle password. Il sale è un valore casuale a 128 bit generato dalla classe RNGCryptoServiceProvider di .NET Framework. Ogni coppia di risposte password/password viene salata con questo valore univoco e il valore di sale viene memorizzato nel campo PasswordSalt della tabella aspnet_Membership. Il risultato dell'hash la password e il sale sono memorizzati nel campo Password. Allo stesso modo, il risultato di hash la risposta della password e il sale è memorizzato nel campo PasswordAnswer. – chobo2

+0

mi chiedo se sia Password + Salt. – chobo2

19

Ecco come lo SqlMembershipProvider genera sale.

private string GenerateSalt() { 
     var buf = new byte[16]; 
     (new RNGCryptoServiceProvider()).GetBytes(buf); 
     return Convert.ToBase64String(buf); 
    } 

È possibile scaricare SQL codice Provider del ASP.NET here.

Il problema che stavo riscontrando era un'applicazione di sviluppo in esecuzione su IIS7. .NET 4.0 utilizzava un diverso algoritmo di hash predefinito rispetto al predefinito HashAlgorithmType per .NET 2.0.

Nel codice di esempio "EncodePassword" di Microsoft, fanno riferimento a Membership.HashAlgorithmType che, a mio avviso, restituisce il valore predefinito per il framework, se non è specificato nello web.config.

Sono riuscito a far funzionare questo metodo GenerateSalt e EncodePassword per la mia applicazione.

Il mio codice combinato:

internal string GenerateSalt() 
{ 
    byte[] buf = new byte[16]; 
    (new RNGCryptoServiceProvider()).GetBytes(buf); 
    return Convert.ToBase64String(buf); 
} 

internal string EncodePassword(string pass, int passwordFormat, string salt) 
{ 
    if (passwordFormat == 0) // MembershipPasswordFormat.Clear 
     return pass; 

    byte[] bIn = Encoding.Unicode.GetBytes(pass); 
    byte[] bSalt = Convert.FromBase64String(salt); 
    byte[] bAll = new byte[bSalt.Length + bIn.Length]; 
    byte[] bRet = null; 

    Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length); 
    Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); 
    if (passwordFormat == 1) 
    { // MembershipPasswordFormat.Hashed 
     HashAlgorithm s = HashAlgorithm.Create("SHA1"); 
     // Hardcoded "SHA1" instead of Membership.HashAlgorithmType 
     bRet = s.ComputeHash(bAll); 
    } 
    else 
    { 
     bRet = EncryptPassword(bAll); 
    } 
    return Convert.ToBase64String(bRet); 
} 
+3

RhinoDevX64, la tua risposta era esattamente quello che stavo cercando! Grazie mille, hai concluso la mia lunga battaglia per cercare di capire come confrontare le mie stringhe con le informazioni hash/sale nel database! –

Problemi correlati