2009-06-03 9 views
30

Używam Mysql i założyłem, że lepiej jest oddzielić dane osobowe użytkowników od ich loginu i hasła na dwie różne tabele, a następnie po prostu odnieść je do siebie .Jak najlepiej przechowywać informacje o użytkowniku oraz login i hasło użytkownika

Uwaga: Aby wyjaśnić mój post, rozumiem techniki zabezpieczania hasła (hash, sól itp.). Po prostu wiem, że jeśli śledzę praktyki z innych części mojego życia (inwestowanie, tworzenie kopii zapasowych, a nawet przechowywania osobistego), to w najgorszym przypadku (składającym się ze stołu lub ognia) posiadanie informacji rozdzielonych między tabelami zapewnia możliwość ochrony dodatkowe dane.

+0

Tylko wyjaśnić; czy chcesz wiedzieć, jak poprawnie przechowywać hasła w bazie danych, czy chcesz po prostu wiedzieć, czy dane profilu użytkownika powinny być oddzielone od danych konta podstawowego? Odpowiedziałem na to pierwsze, ale po ponownym przeczytaniu tego pytania wydaje się, że chcesz tego drugiego. – Rob

+1

Większość odpowiedzi dotyczy metody haszowania i solenia haseł. Jest to cenna informacja, ale nie odnosi się do pytania PO. –

+0

Tak, będę przechowywać hasło za pomocą sha1 i solenia. – Tim

Odpowiedz

35

Nie przechowuj haseł. Jeśli kiedykolwiek siedzi na dysku, może zostać skradziony. Zamiast tego przechowuj hasze hasła. Use the right hashing algorithm, podobnie jak bcrypt (który zawiera sól).

EDYCJA: PO odpowiedział, że rozumie powyższy problem.

Nie ma potrzeby przechowywania hasła w fizycznie innej tabeli niż login. Jeśli jedna tabela bazy danych zostanie naruszona, nie jest to duży krok do uzyskania dostępu do innej tabeli w tej samej bazie danych.

Jeśli jesteś wystarczająco zaniepokojony kwestiami bezpieczeństwa i bezpieczeństwa, możesz rozważyć przechowywanie poświadczeń użytkownika w całkowicie oddzielnym magazynie danych z danych domeny. Jednym z powszechnie stosowanych sposobów jest przechowywanie referencji na serwerze katalogowym LDAP. Może to również pomóc w każdej pracy z pojedynczym logowaniem, którą wykonasz później.

+1

Masz całkowitą rację, MD5 nie jest wystarczająco silny. –

+3

+1 za wszystko oprócz zalecenia SHA. SHA i MD5 są w tej samej, niewystarczającej klasie algosów mieszających - z punktu widzenia bezpieczeństwa, oba bledną w porównaniu do adaptacyjnego mieszania, jak wspomniał Rob poniżej. –

+0

Naprawdę nie odpowiada na pytanie. –

14

Nie ma nic złego w umieszczaniu ich w tym samym stole. W rzeczywistości byłoby to znacznie szybsze, więc zdecydowanie polecam. Nie wiem, dlaczego chciałbyś to rozdzielić.

+1

Poważnie wątpię, że będzie to szybsze, ponieważ sprawdzenie nazwy/hasła i danych użytkownika będzie znajdować się na różnych częściach każdej aplikacji i będzie wykonywane w bardzo różnych momentach. think: potrzebujesz poprawnych danych dla każdego odrzucenia logowania? po zaakceptowaniu, czy musisz sprawdzać hasło za każdym razem, gdy czytasz profil? oczywiście, zwykle nie przejmuję się i składam wszystko razem. ale to tylko dla prostoty, nie dla wydajności. – Javier

+2

Nie, ponieważ musisz wykonać DOŁĄCZYĆ, gdy tylko uzyskasz dane użytkownika. Może to być albo wiele zduplikowanych informacji (np. Nazwa użytkownika i identyfikator przechowywanych w obu itd.), Z których żadna nie jest optymalna. Tak czy inaczej, nie ma powodu, aby podzielić go na dwie różne tabele; to po prostu nie ma sensu, czy to dla wydajności, czy prostoty. –

+1

+1 To jest jedyna odpowiedź (jak dotąd), która odpowiada na pytanie OP. –

0

Powinieneś przechowywać je w tej samej tabeli i używać szyfrowania jednokierunkowego. MD5 będzie działał, ale jest słaby, więc możesz rozważyć coś takiego jak SHA1 lub inną metodę. Nie ma żadnej korzyści z przechowywania dwóch pozycji w osobnych tabelach.

+1

Nie ma czegoś takiego jak szyfrowanie jednokierunkowe; termin jest hashowaniem kryptograficznym. MD5 i SHA1 są szybkimi algorytmami mieszającymi i nie są dobrym pomysłem na mieszanie haseł. Powinieneś podać sól hashowi z losowym przyrostkiem przechowywanym w bazie danych. – Rob

+0

http://en.wikipedia.org/wiki/One-way_encryption W rzeczywistości wybór jednego terminu nad drugim nie jest aż tak istotny, jak pomysł, i wiele osób używa terminu "Szyfrowanie jednokierunkowe". "i są powszechnie rozumiane. –

7

Spróbuję odpowiedzieć na twoje pierwotne pytanie. Posiadanie tego wszystkiego w jednym stole jest w porządku, chyba że po prostu masz dużo danych osobowych do zebrania. W takim przypadku może być sens podzielenie tego. Decyzję tę należy podjąć w oparciu o ilość danych osobowych, z którymi masz do czynienia i jak często muszą być one dostępne.

powiedziałbym większość czasu zrobiłbym coś takiego w jednej tabeli:

UserID, FirstName, LastName, Email, Password, TempPassword 

Ale ... jeśli jesteś zbieranie znacznie więcej niż to. Załóżmy, że zbierasz telefon, faks, datę urodzenia, biografię itp. A jeśli większość informacji jest rzadko dostępna, prawdopodobnie umieściłbym to we własnej tabeli i połączyłem ją z relacją jeden-do-jednego. W końcu, im mniej kolumn masz na stole, tym szybciej będą pojawiać się zapytania względem tego stołu. A czasami ma sens uproszczenie tabel, które są najczęściej dostępne. Jeśli JOIN ma dostęp do tych danych osobistych, masz wydajność, więc to jest coś, co musisz wziąć pod uwagę.

EDYCJA - Wiesz co, właśnie coś wymyśliłem. Jeśli utworzysz indeks na polu nazwy użytkownika lub adresu e-mail (w zależności od tego, co wybierzesz), prawie całkowicie wyeliminujesz niedogodność związaną z wydajnością tworzenia tak wielu kolumn w tabeli użytkownika. Mówię tak, ponieważ za każdym razem, gdy zalogujesz się do klauzuli WHERE, bardzo szybko znajdziesz nazwę użytkownika, jeśli ma ona indeks i nie ma znaczenia, czy masz 100 kolumn w tej tabeli. Więc zmieniłem zdanie. Wrzuciłbym to wszystko do jednego stołu.;)

W każdym przypadku, ponieważ bezpieczeństwo wydaje się być popularnym tematem, hasło powinno być wartością hash. Sugerowałbym SHA1 (lub SHA256, jeśli naprawdę się o to martwisz). TempPassword powinno również używać skrótu i ​​jest dostępne tylko w przypadku zapomnianego hasła. Oczywiście z hashem nie można odszyfrować i wysłać użytkownikowi oryginalnego hasła. Zamiast tego generujesz tymczasowe hasło, na które mogą się logować, a następnie zmuszasz je do zmiany hasła po zalogowaniu.

+0

Nie przechowuj hasła tymczasowego. To dziura. –

+0

Hasło tymczasowe powinno również być hasłem SHA1. Jak to jest dziura? –

+0

co proponujesz zamiast tego? – nickf

3

Po pierwsze, aby podać (miejmy nadzieję) oczywiste, czy można w jakikolwiek sposób w ogóle uniknąć zapisywania nazwy użytkowników i hasła to zrobić; to duża odpowiedzialność i jeśli twój magazyn referencji zostanie naruszony, może zapewnić dostęp do wielu innych miejsc tym samym użytkownikom (z powodu udostępniania haseł).

Jeśli trzeba przechowywać poświadczenia:

  • Nie przechowywać odwracalny formę; przechowuj hash za pomocą rozpoznanego algorytmu, takiego jak SHA-256. Korzystaj z oprogramowania kryptograficznego z wiarygodnego źródła - NIE NALEŻY PODEJMOWAĆ DO WŁASNEGO WŁASNEGO UŻYTKOWANIA, PONIEWAŻ TO PRAWDZIWE.
  • Dla każdego zestawu danych logowania przechowywać sól wraz z danymi zakodowanej; to jest używane do "zalewania" hasha tak, że dwa identyczne hasła nie dają tego samego hasha - ponieważ to daje, że hasła są takie same.
  • Użyj bezpiecznego losowego generatora. Słaba przypadkowość jest główną przyczyną niepowodzeń bezpieczeństwa związanych z szyfrowaniem, a nie algorytmów szyfrowania.

Jeśli trzeba przechowywać odwracalne poświadczeń:

  • wybrać dobry algorytm szyfrowania - AES-256, 3DES (z datą) lub klucz szyfru publicznego. Korzystaj z oprogramowania kryptograficznego z wiarygodnego źródła - NIE NALEŻY PODEJMOWAĆ DO WŁASNEGO WŁASNEGO UŻYTKOWANIA, PONIEWAŻ TO PRAWDZIWE.
  • Dla każdego zestawu danych logowania, przechowywania soli (niezaszyfrowanej) razem z zakodowanymi danymi; służy to do "wstępnego" szyfrowania szyfrującego w taki sposób, że dwa identyczne hasła nie wytwarzają tego samego tekstu szyfrowania - ponieważ daje to pewność, że hasła są takie same.
  • Użyj bezpiecznego losowego generatora. Słaba przypadkowość jest główną przyczyną niepowodzeń bezpieczeństwa związanych z szyfrowaniem, a nie algorytmów szyfrowania.
  • Store szyfrowanie/deszyfrowanie klucz (e) oddzielnie od bazy danych, w pliku zabezpieczonym O/S, dostępny tylko do swojego profilu aplikacji wykonawczego. W ten sposób, jeśli twoja baza danych zostanie naruszona (na przykład poprzez iniekcję SQL), twój klucz nie jest automatycznie podatny na ataki, ponieważ wymagałoby to dostępu do dysku twardego w ogóle. Jeśli Twój O/S obsługuje szyfrowanie plików powiązane z profilem, użyj go - może tylko pomóc i jest ogólnie przezroczysty (np. Szyfrowanie NTFS).
  • Jeśli to możliwe, przechowuj klucze zaszyfrowane za pomocą hasła głównego. Zwykle oznacza to twoją aplikację. będzie wymagało wprowadzenia hasła przy uruchomieniu - nie ma sensu dostarczać go w parametrze ze skryptu, ponieważ jeśli dysk twardy zostanie naruszony, należy założyć, że można wyświetlić zarówno plik klucza, jak i skrypt.
  • Jeśli nazwa użytkownika nie jest konieczne, aby zlokalizować szyfrowania rekordową uwagę zarówno nazwę użytkownika i hasło.
17

Hasła powinny być przechowywane jako kryptograficzny skrót, co jest operacją nieodwracalną, która uniemożliwia odczytanie zwykłego tekstu. Podczas uwierzytelniania użytkowników, wprowadzanie hasła jest poddawane temu samemu procesowi mieszania i porównywane są skróty.

Unikaj używania szybkiego i taniego skrótu, takiego jak MD5 lub SHA1; celem jest uczynienie kosztownym dla atakującego obliczania tablic kolorów (na podstawie kolizji mieszania); szybki skrót przeciwdziała temu. Używanie drogiego skrótu nie stanowi problemu w przypadku scenariuszy uwierzytelniania, ponieważ nie będzie miało wpływu na pojedynczy przebieg wartości mieszania.

Oprócz mieszania posól hasz o losowo wygenerowanej wartości; nonce, który jest następnie przechowywany w bazie danych i łączony z danymi przed hashowaniem. Zwiększa to liczbę możliwych kombinacji, które muszą być generowane podczas obliczania kolizji, a tym samym zwiększa ogólną złożoność czasu generowania tabel kolorów.

Twoja kolumna hash hash może mieć stałą długość; Twój hash kryptograficzny powinien wyprowadzać wartości, które mogą być zakodowane na stałą długość, która będzie taka sama dla wszystkich skrótów.

O ile to możliwe, unikaj zwijania własnego mechanizmu uwierzytelniania hasłem; użyj istniejącego rozwiązania, takiego jak bcrypt.

Doskonałe objaśnienie obsługi haseł i tego, co należy zwrócić na siebie, można znaleźć na stronie http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes.

Uwaga końcowa: pamiętaj, że jeśli osoba atakująca uzyska dostęp do Twojej bazy danych, najprawdopodobniej Twoja bezpośrednia troska powinna dotyczyć wszelkich poufnych lub personalnie identyfikujących informacji, do których może mieć dostęp, oraz wszelkich szkód, jakie mogły one wyrządzić.

+2

Blog został przeniesiony na http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html – jwhitlock

+1

+1 dla 'bcrypt' – dave1010

+0

nigdy nie używaj bcrypt zobacz tutaj http://bugs.debian.org/700758 – nikoss

2

W moim osobistym doświadczeniu przechowywanie danych osobowych i danych logowania w poszczególnych bazach danych jest najlepszą praktyką w tym przypadku. Powodem jest to, że należy wykonać iniekcję SQL, jest ona ograniczona (chyba że infiltrator zna wewnętrzny układ twoich baz danych) do tabeli, której dane dotyczą, w przeciwieństwie do zapewnienia dostępu do całego konglomeratu danych.

Należy jednak pamiętać, że może się to zdarzyć kosztem konieczności wykonywania większej liczby zapytań, a więc działania skutecznego.

+2

LUB możesz być ostrożnym programistą i zapobiegać atakom SQL injection w pierwszej kolejności. ;) –

+0

Oczywiście = P Oczywiście, dla każdego zastosowanego środka zaradczego, istnieje jednak obejście. Więc równie dobrze może zmniejszyć straty i utrudnić dostanie się do niezwiązanych informacji. – Jason

2

Czy wszystkie te dane zawsze będą miały relację 1: 1 z użytkownikiem? Jeśli możesz przewidzieć, że użytkownicy mają wiele adresów, numerów telefonów itp., Możesz podzielić dane osobowe na osobną tabelę.

Powiązane problemy