2009-08-12 11 views
20

Jak członkostwa ASP.NET wygenerować swój klucz soli, a następnie w jaki sposób je zakodować (czyli jest to sól + hasło lub hasło + sól)?Sól członkowska ASP.NET?

Używam członkostwa SHA-1, ale chciałbym odtworzyć te same sole, więc wbudowane elementy członkowskie mogą mieszać te same rzeczy, co moje rzeczy.

Edit 2: Nieważne. Źle przeczytałem i pomyślałem, że mówi bajty, a nie bity. Przekazałem 128 bajtów, a nie 128 bitów.

Edytuj: Próbowałem to zrobić. To jest to, co mam, Nie można sprawdzić, czy członkostwo ASP.NET rozpozna to, ale hash hasłem wygląda blisko. Po prostu nie wiem, jak przekonwertować go na base64 dla soli.

Zrobiłem to

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

int test = base64Salt.Length; 

długość testu jest 172, który jest dobrze ponad 128 bitów więc to, co robię źle?

To właśnie ich sól wygląda

vkNj4EvbEPbk1HHW+K8y/A== 

To właśnie moja sól wygląda

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

Można sprawdzić moją odpowiedź na tej stronie: SO http://stackoverflow.com/questions/530426/reimplement-asp-net-membership-and- user-password-hashing-in-ruby/8184569 # 8184569 –

Odpowiedz

18

What is default hash algorithm that ASP.NET membership uses? ma dobrą dyskusję domyślnego algorytmu.

Mam nadzieję, że to pomoże!

Edit- Odpowiedź miałem na myśli to kod na górnym stanowisku,

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

Są łącząc Unicode soli + karnet użyciu BlockCopy

- W odpowiedzi na pytanie:

Oba algorytmy są niezbędne i spełniają różne role ...

RNG Crypto służy do generowania soli. Jest to zasadniczo długi ciąg losowych danych. Jest to generowane i przechowywane dla każdego użytkownika. Zazwyczaj robi się to po utworzeniu użytkownika lub zmianie hasła.

BlockCopy to metoda, którą łączą sól z hasłem. Powyższy kod w zasadzie równa się soli + hasło.

Nie można odtworzyć wartości soli, ponieważ jest całkowicie losowa. Jest jednak przechowywany dla każdego użytkownika przez framework.

Łącząc sól z hasłem i mieszania go z zastosowaniem techniki powyżej pozwoli zweryfikować użytkowników haseł stosując wartość przechowywaną hashed przez ramy.

Myślę, że obaj czytamy twoje pytanie inaczej.Wysłany przeze mnie kod nie będzie generował twojej soli, ale pozwoli ci użyć go w sposób zgodny z członkostwem ASP.NET.

Przepraszam, moje wyjaśnienie nie jest najlepsze - czy to odpowiada na twoje pytanie?

+0

Nie mówi ci, w jaki sposób Microsoft robi sól. –

+0

Górny post pokazuje algorytm - skopiowałem go tutaj dla jasności. –

+0

Przepraszam- widzę co masz na myśli. Zakładałem, że szukał sposobu, w jaki został połączony, aby odtworzyć z istniejących danych. –

1

Oto jeden sposób robienia tego. Sól jest tylko liczba losowa, można użyć klasy RNGCryptoServiceProvider w bibliotece ramowej produkować dużą liczbę losową użyć jako sól

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

Witam Znalazłem na msdn to "PasswordSalt: Losowo wygenerowana 128-bitowa wartość używana do solnych skrótów hasła, przechowywana w postaci zakodowanej w 64-literach" http://msdn.microsoft.com/en-us/library /aa478949.aspx Więc co mam zrobić w salt_size do 128? co powiesz na rozmiar skrótu? – chobo2

+0

mają również ten MembershipPasswordFormat.Hashed (domyślnie), który przechowuje solone hashe generowane z haseł i odpowiedzi hasła. Sól jest losową 128-bitową wartością generowaną przez klasę RNGCryptoServiceProvider .NET Framework. Każda para odpowiedzi hasło/hasło jest solona z tą unikalną wartością, a sól jest przechowywana w polu PasswordSalt tabeli aspnet_Membership. Wynik skrótu hasła i soli jest przechowywany w polu Hasło. Podobnie, wynik hashowania odpowiedzi hasła i sól są przechowywane w polu PasswordAnswer. – chobo2

+0

sprawia, że ​​zastanawiam się, czy to Password + Salt. – chobo2

19

Oto jak SQLMembershipProvider wytwarza sól.

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

Można pobrać kod dostawcy SQL ASP.NET here.

Problem, który miałem, to aplikacja programistyczna działająca na IIS7. .NET 4.0 używał innego domyślnego algorytmu skrótu niż domyślny HashAlgorithmType dla .NET 2.0.

W przykładowym kodzie źródłowym "EncodePassword" firmy Microsoft znajdują się odniesienia do Membership.HashAlgorithmType, które, moim zdaniem, zwracają wartość domyślną dla frameworka, jeśli nie określono go w web.config.

Udało mi się uzyskać zarówno metodę GenerateSalt, jak i EncodePassword, aby działała dla mojej aplikacji.

Mój kod kombinowany:

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, twoja odpowiedź była dokładnie tym, czego szukałem! Bardzo dziękuję, zakończyłeś moją długą walkę, próbując dowiedzieć się, jak porównać moje struny z hash/solą w bazie danych! –

Powiązane problemy