Czy BCrypt jest dobrym algorytmem mieszania do użycia w C #? Gdzie mogę to znaleźć? [Zamknięte]

129

Czytałem, że przy haszowaniu hasła wielu programistów zaleca stosowanie algorytmu BCrypt.

Programuję w C # i zastanawiam się, czy ktoś wie o dobrej implementacji BCrypt? Znalazłem tę stronę , ale tak naprawdę nie wiem, czy jest fałszywa, czy nie.

O czym należy pamiętać przy wyborze schematu mieszania haseł? Czy BCrypt jest „dobrą” implementacją?

Svish
źródło

Odpowiedzi:

150

Po pierwsze, kilka ważnych terminów:

Haszowanie - czynność polegająca na pobraniu łańcucha i utworzeniu sekwencji znaków, których nie można przywrócić do oryginalnego ciągu.

Szyfrowanie symetryczne - (zwykle określane po prostu jako „szyfrowanie”) - czynność polegająca na pobraniu ciągu znaków i utworzeniu sekwencji znaków, które można odszyfrować do oryginalnego ciągu przy użyciu tego samego klucza szyfrowania, który go zaszyfrował.

Rainbow Table - tabela przeglądowa zawierająca wszystkie odmiany znaków zahaszowanych w określonym algorytmie haszującym.

Sól - znany losowy ciąg dołączany do oryginalnego ciągu przed jego zhaszowaniem.

W przypadku .NET Framework Bcrypt nie ma jeszcze zweryfikowanej implementacji referencyjnej. Jest to ważne, ponieważ nie ma możliwości sprawdzenia, czy istniejąca implementacja ma poważne wady. Możesz pobrać implementację BCrypt dla .NET tutaj . Nie wiem wystarczająco dużo o kryptografii, aby powiedzieć, czy jest to dobra czy zła implementacja. Kryptografia to bardzo głęboka dziedzina. Nie próbuj budować własnego algorytmu szyfrowania . Poważnie.

Jeśli zamierzasz wdrożyć własne zabezpieczenie hasłem (westchnienie), musisz zrobić kilka rzeczy:

  1. Użyj stosunkowo bezpiecznego algorytmu mieszania .
  2. Podsól każde hasło, zanim zostanie zaszyfrowane.
  3. Użyj unikalnej i długiej soli dla każdego hasła i przechowuj sól z hasłem.
  4. Wymagaj silnych haseł .

Niestety, nawet jeśli to wszystko zrobisz, zdeterminowany haker nadal mógłby potencjalnie odgadnąć hasła, zajęłoby mu to naprawdę dużo czasu. To twój główny wróg: czas .

Algorytm bcrypt działa, ponieważ trwa pięć rzędów wielkości dłużej niż hash hasła MD5 ; (i nadal znacznie dłużej niż AES lub SHA-512). Zmusza to hakera do spędzenia dużo więcej czasu na utworzeniu tęczowej tabeli do wyszukiwania haseł, co znacznie zmniejsza prawdopodobieństwo, że Twoje hasła będą narażone na włamanie.

Jeśli solisz i haszujesz swoje hasła, a każda sól jest inna, potencjalny haker musiałby stworzyć tęczową tabelę dla każdej odmiany soli , aby mieć tęczową tabelę dla jednego solonego + zaszyfrowanego hasła. Oznacza to, że jeśli masz 1 milion użytkowników, haker musi wygenerować 1 milion tęczowych tabel. Jeśli używasz tej samej soli dla każdego użytkownika, haker musi wygenerować tylko 1 tęczową tabelę, aby pomyślnie zhakować Twój system.

Jeśli nie solisz swoich haseł, atakujący musi tylko pobrać istniejącą tabelę Rainbow dla każdej implementacji (AES, SHA-512, MD5) i sprawdzić, czy jedna z nich pasuje do skrótu. To już zostało zrobione , napastnik nie musi samodzielnie obliczać tych tabel Rainbow .

Nawet mając to wszystko, musisz stosować dobre praktyki bezpieczeństwa . Jeśli uda im się z powodzeniem użyć innego wektora ataku (XSS, SQL Injection, CSRF itp . ) W Twojej witrynie, dobre bezpieczeństwo hasła nie ma znaczenia. Brzmi to jak kontrowersyjne stwierdzenie, ale pomyśl o tym: jeśli uda mi się uzyskać wszystkie informacje o użytkowniku za pomocą ataku SQL injection lub nakłonić użytkowników do przesłania mi plików cookie za pośrednictwem XSS, to nie ma znaczenia, jak dobre jest Twoje hasło bezpieczeństwo jest .

Inne zasoby:

  1. Jeff Atwood: Uproszczone szyfrowanie .NET (świetne do przeglądu haszowania)
  2. Jeff Atwood: Właśnie się zalogowałem jako ty
  3. Jeff Atwood: Prawdopodobnie niepoprawnie przechowujesz hasła
  4. Jeff Atwood: Speed ​​Hashing

Uwaga: proszę polecić inne dobre zasoby. Musiałem przeczytać tuzin artykułów dziesiątek autorów, ale niewielu pisze na ten temat tak wyraźnie, jak Jeff. Edytuj artykuły w miarę ich wyszukiwania.

George Stocker
źródło
może dodać do swojego paragrafu solnego, że sól musi być wybrana losowo
Jacco
2
@Jacco Dobre połączenie, dodano. Chociaż to nie jest takie ważne. Możesz po prostu użyć znacznika czasu logowania do soli. Różnica polega na tym, że atakujący musi następnie ponownie obliczyć tęczową tablicę dla każdej soli. To sprawia, że ​​jest to trudne, nie dlatego, że jest wybierane losowo. Sprawienie, by było losowe, spowodowałoby dodanie kolejnej warstwy zaciemnienia, ale jest to bezużyteczne, gdy atakujący będzie w stanie zobaczyć twoją bazę danych (co jest problemem, który przede wszystkim powoduje cały nasz ból serca).
George Stocker
3
Niekoniecznie, sól nie musi być tajemnicą, po prostu unikalna dla każdego przypadku. Ponieważ unikalność (jak na całym świecie) nie jest możliwa, losowość jest następną najlepszą rzeczą. Ponadto znacznik czasu nie jest dobrą solą, ponieważ nie ma wystarczającej entropii.
Jacco
7
Nie zgadzam się z Twoim stwierdzeniem „Jeśli uda im się z powodzeniem używać XSS lub wstrzykiwania SQL, dobre bezpieczeństwo hasła nie ma znaczenia”. Wręcz przeciwnie, jeśli uda im się z powodzeniem wstrzyknąć XSS lub SQL do Twojej witryny, dobre zabezpieczenie hasła jest jeszcze ważniejsze. Kluczem jest tutaj „głęboka obrona” - powinieneś zaostrzyć zabezpieczenia na tyle, na ile jest to praktyczne na każdej warstwie aplikacji.
jammycakes
2
@jammycakes Absolutely; mój punkt widzenia został utracony: nie można po prostu powiedzieć: „Hej, haszujemy i solimy nasze hasła,„ wszystko w porządku ”!
George Stocker,
74

Nie możesz używać BCrypt w .NET. Państwo musi używać PBKDF2 jak jest z wbudowanego w .NET wdrażania ramowej. Jest to jedyna ogólnie dostępna, zweryfikowana kryptograficznie implementacja w .NET, będąca algorytmem zalecanym przez NIST .

StackId wcześniej używał BCrypt i przeniósł się do PBKDF2 z tego właśnie powodu:

Dla ciekawskich haszujemy hasła za pomocą PBKDF2. Relavent kod jest tutaj ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ), przez kilka warstw pośrednich. We wcześniejszej iteracji używaliśmy BCrypt; ale przeniósł się do PBKDF2, ponieważ jest wbudowany w framework .NET, podczas gdy BCrypt wymagałby od nas weryfikacji implementacji (nie jest to małe przedsięwzięcie).

Kevin Montrose, 27 maja 2011

(Zaktualizowany link na GitHub)

Edycja: znaczenie zweryfikowanego w kategoriach kryptograficznych wydaje się nie być łatwe do zrozumienia, zweryfikowana implementacja oznacza, że ​​kryptograficznie udowodniono, że została wdrożona bez błędów. Koszt tego może łatwo osiągnąć 20 000 USD lub więcej. Przypominam sobie to, kiedy szukałem informacji na temat OpenSSL i czytałem, gdzie stwierdzili, że nie ukończyli całego procesu weryfikacji, ale jeśli potrzebujesz w pełni zweryfikowanego, mogą wskazać Ci właściwą ścieżkę i wspomnieć o związanych z tym kosztach. Niektóre wymagania rządowe obejmują upoważnienia do zweryfikowanych algorytmów szyfrowania.

Implementacje bcrypt w .NET nie zostały zweryfikowane. Korzystając z niezweryfikowanej implementacji szyfrowania, nie można być absolutnie pewnym, że nie ma w niej ani zamierzonych złośliwych błędów, takich jak zezwolenie na backdoor na to, co jest zaszyfrowane, lub niezamierzonych błędów implementacji, które skutkują kryptograficznie niezabezpieczonymi danymi.

Edycja 2014: Dla każdego, kto kwestionuje imperatywność używania zweryfikowanych algorytmów kryptograficznych, spójrz na zniszczenia, które zostały dokonane przez oszołomiony hack wykorzystany w OpenSSL. To jest koszt korzystania z niezweryfikowanej implementacji. To bezpieczne… dopóki nie okaże się, że każda osoba może po prostu odczytać całą zawartość pamięci serwera.

Autor zmiany, która wprowadziła Heartbleed, Robin Seggelmann, stwierdził, że „przegapił walidację zmiennej zawierającej długość” i zaprzeczył jakiemukolwiek zamiarowi przedstawienia błędnej implementacji. Po ujawnieniu Heartbleed, Seggelmann zasugerował skupienie się na drugim aspekcie, stwierdzając, że OpenSSL nie jest recenzowany przez wystarczającą liczbę osób.

To jest definicja niezweryfikowanej implementacji. Nawet najmniejsza wada może spowodować sparaliżowanie całego zabezpieczenia.

Edycja 2015: Usunięto język oparty na rekomendacjach i zastąpiono absolutami. Osadzono oryginalny komentarz Kevina Montrose'a dla potomności.

Chris Marisic
źródło
25
Cytując link do komentarza: „[przenieśliśmy się] do PBKDF2, ponieważ jest on wbudowany w platformę .NET, podczas gdy BCrypt wymagałby od nas weryfikacji implementacji”. Zauważ, że komentarz nie mówi, że algorytm jest lepszy, tylko że SE Dev Team uważa wbudowaną implementację PBKDF2 za bardziej zaufaną niż zewnętrzną bibliotekę (co ostatecznie jest wezwaniem do oceny).
Piskvor opuścił budynek
3
@Piskvor Zaktualizowałem moją odpowiedź. Nie chodzi o to, co zespół SO uważa za bezpieczne, ale o ocenę między z natury bezpieczną lub miejmy nadzieję. To drugie, jeśli chodzi o kryptografię, jest niedopuszczalne.
Chris Marisic,
6
Zastanawiam się, jak SO zmigrował wszystkie zaszyfrowane hasła bcrypt do nowych skrótów? Czy nie potrzebowaliby surowych haseł, aby zaszyfrować je przy użyciu nowego algorytmu?
Dharmendar Kumar 'DK'
8
@DK Myślę, że nawet nie musisz prosić ich o zresetowanie haseł. Uważam, że przy następnym logowaniu (gdzie podają swoje hasło w postaci zwykłego tekstu) możesz to zrobić.
Matt Kocaj,
13
To kiepska rada i jestem zaskoczony, że ma tak wiele pozytywnych opinii. Weryfikacja implementacji BCrypt w zarządzanym języku jest dużo, dużo bardziej trywialna niż weryfikacja czegoś takiego jak cała implementacja SSL w C. Heartbleed jest całkowicie nieistotna; Lepiej byłoby wspomnieć o czymś takim, jak problemy z wymuszaniem typu PHP przy sprawdzaniu równości skrótu. Ponadto PBKDF2 jest w dużej mierze odpowiedni w sensie praktycznym, ale jest algorytmem KDF, a nie algorytmem mieszania haseł, podczas gdy BCrypt jest lepiej dopasowany. Niezależnie od tego, i tak byłoby o wiele bardziej sensowne użycie Argon2 w dzisiejszych czasach, dla którego istnieje dobrze przetestowana biblioteka C #
Polynomial