Najlepszy sposób na przechowywanie hasła w bazie danych [zamknięte]

474

Pracuję nad projektem, który musi mieć uwierzytelnianie (nazwa użytkownika i hasło)

Łączy się również z bazą danych, więc pomyślałem, że przechowam tam nazwę użytkownika i hasło. Wydaje się jednak, że posiadanie haseł nie jest dobrym pomysłem, jak pole tekstowe w tabeli siedzącej w bazie danych.

Używam C # i łączę się z serwerem ekspresowym 2008. Czy ktoś może zasugerować (z jak największą liczbą przykładów), jaki byłby najlepszy sposób przechowywania tego typu danych?

PS Jestem otwarty na pomysł, aby te informacje nie były przechowywane w bazie danych, jeśli można podać dobry powód

Crash893
źródło
1
Cokolwiek robisz, jeśli korzystasz z szyfrowania, nie przechowuj klucza w kodzie, jak wspomniano w poprzednim plakacie. To tylko zła praktyka.
Woody,
12
„Jak poprawnie hasła?” to ważne pytanie. To trudny problem, a błędy mają poważne konsekwencje (przypomnij sobie, co stało się z Tesco i LinkedIn). Myślę, że to pytanie powinno zostać ponownie otwarte na stronie programmers.stackexchange.com
Pułkownik Panic
2
Lepiej trzymać się standardów - patrz en.wikipedia.org/wiki/PBKDF2 Musisz tylko znaleźć implementację w swoim języku
Boris Treukhov
5
Odpowiedź na to pytanie jest obszerna na forum bezpieczeństwa
gioele

Odpowiedzi:

405

Masz rację, że przechowywanie hasła w polu tekstowym to okropny pomysł. Jednak, jeśli chodzi o lokalizację , w większości przypadków, które napotkasz (i szczerze mówiąc, nie mogę wymyślić żadnych kontrprzykładów), przechowywanie reprezentacji hasła w bazie danych jest właściwe. Przez reprezentację to znaczy, że chcesz hash hasła przy użyciu soli (która powinna być inna dla każdego użytkownika) i bezpieczny algorytm 1-way i sklep , który , wyrzucać oryginalnego hasła. Następnie, gdy chcesz zweryfikować hasło, haszujesz wartość (używając tego samego algorytmu haszującego i soli) i porównujesz ją z wartością haszowaną w bazie danych.

Chociaż dobrze jest o tym myśleć i jest to dobre pytanie, w rzeczywistości jest to duplikat tych pytań (przynajmniej):

Aby wyjaśnić nieco więcej na temat bitu solenia, istnieje niebezpieczeństwo, że po prostu wyszyfrujesz hasło i zapiszesz to, że jeśli intruz przejmie twoją bazę danych, może nadal używać tak zwanych tęczowych tabel, aby móc „odszyfrować” hasło (przynajmniej te, które pojawiają się w tabeli tęczy). Aby obejść ten problem, programiści dodają sól do haseł, która, jeśli jest właściwie wykonana, sprawia, że ​​ataki tęczy są po prostu niewykonalne. Zauważ, że powszechnym nieporozumieniem jest po prostu dodanie tego samego unikalnego i długiego ciągu do wszystkich haseł; chociaż nie jest to okropne , najlepiej jest dodawać unikalne sole do każdego hasła. Przeczytaj to, aby uzyskać więcej.

Paolo Bergantino
źródło
39
Miałem na myśli przechowywanie hasła w bazie danych, a nie przechowywanie go w innym miejscu. Wyjęcie tego zdania z kontekstu wydaje się, że popieram przechowywanie prostych haseł, jeśli czytasz resztę, oczywiście nie.
Paolo Bergantino
13
Nie tylko to, co powiedziałem, skierowałem go do wielu postów, które omawiają sole i tak dalej ...
Paolo Bergantino
1
@Paolo Bergantino: na pewno nie ma literówki w swoim poście? Mówi: „W większości przypadków, które napotkasz (i szczerze mówiąc, nie mogę wymyślić żadnych kontrprzykładów), przechowywanie hasła w bazie danych jest właściwe.” ??? To wydaje się zaprzeczać twoim komentarzom
Mitch Wheat
3
To, co powiedział Paolo, jest sprzeczne. Solony hash hasła nie jest hasłem. Przechowywanie solonego skrótu hasła w bazie danych nie powoduje zapisania hasła w bazie danych. Treść odpowiedzi jest całkowicie odpowiednia, ale jej pierwsze zdanie jest bardzo mylące.
Robert Rossney,
39
@Robert: To niebezpiecznie zbliża się do drobnej gry semantyki, ale mimo to ją naprawię ...
Paolo Bergantino
54

Tło Nigdy ... naprawdę ... nie musisz znać hasła użytkownika. Chcesz tylko zweryfikować, że przychodzący użytkownik zna hasło do konta.

Hash It: Przechowuj hash użytkowników (szyfrowanie jednokierunkowe) za pomocą silnej funkcji skrótu. Wyszukiwanie hasła „c # encrypt passwords” daje mnóstwo przykładów.

Zobacz online twórcę skrótów SHA1, aby dowiedzieć się, co wytwarza funkcja skrótu (ale nie używaj SHA1 jako funkcji skrótu, użyj czegoś silniejszego, takiego jak SHA256).

Teraz hashowane hasła oznaczają, że ty (i złodzieje baz danych) nie powinieneś być w stanie przywrócić tego hasha z powrotem do oryginalnego hasła.

Jak z tego korzystać: Ale, jak mówisz, jak korzystać z tego zmasowanego hasła przechowywanego w bazie danych?

Gdy użytkownik się zaloguje, poda Ci nazwę użytkownika i hasło (w oryginalnym tekście). Wystarczy użyć tego samego kodu skrótu, aby zakodować to wpisane hasło, aby uzyskać zapisaną wersję.

Porównaj więc dwa hashowane hasła (hash bazy danych dla nazwy użytkownika oraz wpisanego i hashowanego hasła). Możesz sprawdzić, czy „to, co wpisali”, „pasuje” do tego, co wprowadził pierwotny użytkownik dla swojego hasła ”, porównując ich skróty.

Dodatkowy kredyt:

Pytanie: Gdybym miał twoją bazę danych, czy nie mógłbym po prostu wziąć crackera takiego jak John the Ripper i zacząć tworzyć skróty, dopóki nie znajdę pasujących do zapisanych, zakodowanych haseł? (ponieważ użytkownicy wybierają krótkie, słownikowe słowa i tak ... powinno być łatwo)

Odpowiedź: Tak ... tak, mogą.

Powinieneś więc „zasolić” swoje hasła. Zobacz artykuł Wikipedii na temat soli

Zobacz przykład „Jak mieszać dane za pomocą soli” w C #

joej
źródło
14
Niezły post, z wyjątkiem jednej rzeczy: md5 i sha1 zostały zepsute. Prawdopodobnie powinieneś zastosować silniejszy algorytm, taki jak być może rodzina SHA2.
Paolo Bergantino
3
Dzięki Paolo - masz rację. Ponieważ korzystanie z SHA2 jest tak proste, jak korzystanie z MD5 i SHA1, użyj silniejszego algorytmu skrótu.
joej
5
SHA-1 nie został zepsuty. Ale parafrazując Bruce'a Schneiera: idź, nie biegnij, do SHA-2.
Ian Boyd
2
„Więc powinieneś„ posolić ”swoje hasła”… Ale sól jest zwykle przechowywana w bazie danych wraz z hasłem, więc jak to pomaga? Atakujący musi po prostu dodać sól do fraz atakujących słownik, na których testuje. W jaki sposób jest to bezpieczniejsze, niż nie ujawnia zduplikowanych haseł?
trusktr
4
@joej „Nigdy… naprawdę… nie musisz znać hasła użytkownika” - to założenie bardzo krótkowzroczne. Istnieje wiele rodzajów aplikacji, w których przechowywanie hasła w sposób umożliwiający jego odzyskanie jest naprawdę konieczne. Na przykład aplikacja, która musi często logować się do innego systemu z zapisanymi poświadczeniami, dostarczonymi i zaktualizowanymi przez użytkownika.
Francisco Zarabozo
29

Jako zahartowany solą skrót, wykorzystujący bezpieczny algorytm, taki jak sha-512.

Nilamo
źródło
6
Moim zdaniem do przechowywania haseł należy zawsze używać powolnych algorytmów (np. Blowfish). Ten writeup jest znacznie lepsza odpowiedź: security.stackexchange.com/questions/211/... . Wystarczy umieścić go tutaj, ponieważ ta strona wciąż pojawia się wysoko w wynikach wyszukiwania.
Dynom
2
Postępowanie zgodnie z tą radą dotyczącą przechowywania haseł byłoby bardzo złe.
mlissner
27

Najlepszą praktyką bezpieczeństwa nie jest przechowywanie hasła w ogóle (nawet nieszyfrowanego), ale przechowywanie solonego skrótu (z unikalną solą na hasło) zaszyfrowanego hasła.

W ten sposób (praktycznie) niemożliwe jest odzyskanie hasła w postaci zwykłego tekstu.

Mitch Pszenica
źródło
11
Wayne, soląc przed obliczeniem skrótu, tablica tęczy zostaje skutecznie pokonana, pod warunkiem, że sól ma wystarczającą wielkość.
Mike Rosenblum,
11
@Wayne Hartman: Nie tak. Jeśli wartość soli jest widoczna, musisz wygenerować nową tęczową tabelę dla tej konkretnej wartości soli. Celem tabeli tęczy jest wcześniejsze obliczenie wartości skrótu. I nikt nie będzie miał tęczowego stołu dla swojej konkretnej soli.
Ian Boyd
10

Całkowicie polecam przeczytanie artykułów „ Wystarczy Tęczowe tablice: Co musisz wiedzieć o bezpiecznych schematach haseł [martwy link, kopia w archiwum internetowym ] i jak bezpiecznie przechowywać hasło .

Wielu programistów, łącznie ze mną, myśli, że rozumie bezpieczeństwo i mieszanie. Niestety większość z nas po prostu tego nie robi.

zebrabox
źródło
1
@Johan Wygląda na to, że link jest teraz zepsuty, a szkoda. Oto alternatywne codahale.com/how-to-safely-store-a-password
zebrabox
6

Mogę być nieco nie na temat, ponieważ wspomniałeś o potrzebie nazwy użytkownika i hasła, a moje zrozumienie problemu nie jest wprawdzie najlepsze, ale czy OpenID jest czymś, co warto rozważyć?

Jeśli użyjesz OpenID, w ogóle nie przechowujesz żadnych poświadczeń, jeśli dobrze rozumiem technologię, a użytkownicy mogą korzystać z poświadczeń, które już posiadają, unikając potrzeby tworzenia nowej tożsamości, która będzie specyficzna dla Twojej aplikacji.

Może jednak nie być odpowiedni, jeśli dana aplikacja jest przeznaczona wyłącznie do użytku wewnętrznego

RPX zapewnia łatwy i łatwy sposób zintegrowania obsługi OpenID z aplikacją.

Crippledsmurf
źródło
Zgadzam się, że OpenID Rock People stoi twarzą w twarz, ale w przypadku tej aplikacji jest to wewnętrzna baza danych dla firmy. Wątpię, czy chcieliby, aby każda starsza osoba zalogowała się. również dostęp do sieci nie jest potrzebny, aby ta aplikacja działała poprawnie, więc nie chciałbym jej wymagać.
Crash893
3

W twoim scenariuszu możesz spojrzeć na członkostwo asp.net, dobrą praktyką jest przechowywanie hasła użytkownika jako łańcucha mieszanego w bazie danych. możesz uwierzytelnić użytkownika, porównując zakodowane hasło przychodzące z hasłem przechowywanym w bazie danych.

Wszystko zostało zbudowane do tego celu, sprawdź członkostwo asp.net

Ray Lu
źródło
1

Chciałbym MD5 / SHA1 hasło, jeśli nie musisz mieć możliwości cofnięcia skrótu. Kiedy użytkownicy logują się, możesz po prostu zaszyfrować podane hasło i porównać je z hashem. W tym przypadku kolizje mieszania są prawie niemożliwe, chyba że ktoś uzyska dostęp do bazy danych i zobaczy skrót, dla którego już ma kolizję.

waiwai933
źródło
2
Nie używałbym MD5 do mieszania - jest to w zasadzie zepsuty mscs.dal.ca/~selinger/md5collision
zebrabox
3
Właściwie to nie jest tak zepsute. Co mogą zrobić, to znaleźć tę samą wartość skrótu dla dwóch różnych plików. To, czego nie mogą zrobić, to odwrócić MD5 i uzyskać działające hasło.
waiwai933
2
Czy to też nie byłoby zepsute? Wystarczy wpisać inne hasło, które generuje ten sam skrót, i jesteś w. Nie musisz znać oryginalnego hasła. Sposobem na rozwiązanie tego jest zasolenie hasła przed mieszaniem.
mjuarez
2
@mjuarez, jeśli dodasz sól do hasła przed użyciem MD5, kolizja nie ma znaczenia, ponieważ nie możesz użyć drugiego hasła
WiiMaxx