2009-09-01 12 views
5

Jak napisać/złożyć bezpieczny login w PHP? website developer guide powiedział, że nie powinienem wykonywać własnych, więc odwoływanie się do próbek dostępnych przez Google jest bezużyteczne.Bezpieczne logowanie z prawidłowym uwierzytelnieniem w PHP

Jak to robią zawodowcy? Powiedzmy, że budujesz światowej klasy aplikację w szynach, czy te same biblioteki/techniki będą tutaj użyteczne?

Dzięki

+0

Możesz zajrzeć na https://github.com/delight-im/PHP-Auth, który jest zarówno agnostyczny, jak i agnostyczny. – caw

Odpowiedz

20

W Railsach zazwyczaj korzystano z wcześniej istniejącej biblioteki. Uwierzytelnianie łatwo jest zrobić źle, a problem został rozwiązany tyle razy, że rzadko jest warte wysiłku, aby go rozwiązać ponownie. Jeśli jesteś zainteresowany pisaniem własnych implementacji, opiszę, jak działa nowoczesne uwierzytelnianie.

Naiwną metodą uwierzytelniania użytkownika jest przechowywanie jego hasła w bazie danych i porównywanie go z hasłem przesłanym przez użytkownika. Jest to proste, ale niewiarygodnie niepewne. Każdy, kto może odczytać twoją bazę danych, może wyświetlić hasło każdego. Nawet jeśli zastosujesz kontrolę dostępu do bazy danych, ty (i twoi użytkownicy) jesteście podatni na atak wobec każdego, kto się do nich włamie.

Właściwą formą jest użycie kryptograficznej funkcji skrótu do przetwarzania hasła po wybraniu, a następnie za każdym razem, gdy jest ono przesyłane. Dobra funkcja hashowania jest praktycznie nieodwracalna - nie możesz wziąć hasha i zmienić go z powrotem w hasło. Tak więc, kiedy użytkownik się loguje, bierzesz przedłożone hasło, mieszasz je i porównujesz z hashem w bazie danych. W ten sposób nigdy nie przechowujesz samego hasła. Z drugiej strony, jeśli użytkownik zapomni hasła, należy go zresetować, a nie wysłać do niego.

Nawet to jest jednak podatne na pewne ataki. Jeśli atakujący zdobędzie twoje hasłowe skróty i wie, w jaki sposób mieszasz swoje hasła, może dokonać ataku słownikowego: po prostu bierze każde słowo ze słownika i haszy tego słowa, zachowując je z oryginałem. Ta struktura danych nazywa się tabelą tęczową. Następnie, jeśli dowolne ze skrótów słownikowych pasuje do wartości hash hasła, atakujący może stwierdzić, że hasło jest słownikiem słownikowym, które miesza się z tym hasłem. W skrócie, osoba atakująca, która może odczytać twoją bazę danych, może nadal logować się na konta ze słabymi hasłami.

Rozwiązaniem jest to, że przed hashowaniem hasła jest ono łączone (zwykle łączone lub xor'd) z wartością zwaną solą, która jest unikalna dla każdego użytkownika. Może być losowo generowany lub może być znacznikiem czasu utworzenia konta lub innym. Następnie atakujący nie może korzystać z tabeli tęczowej, ponieważ każde hasło jest w zasadzie nieco inaczej mieszane; musiałby stworzyć oddzielną tęczową tabelę dla każdej odrębnej soli (praktycznie dla każdego konta), która byłaby zaporowo kosztowna obliczeniowo.

Powtórzę radę innych osób udzielających odpowiedzi: nie jest to proste, a nie musisz tego robić, ponieważ zostało to zrobione wcześniej, a jeśli zrobisz to sam, masz bardzo duże szanse na zrobienie błąd i nieumyślne naruszenie bezpieczeństwa twojego systemu. Ale jeśli z jakiegoś powodu naprawdę, naprawdę chcesz napisać samemu, mam nadzieję, że dostarczyłem (niepełny!) Zarys tego, jak to się robi.

+2

+1 - Za bardzo dobrą odpowiedź. –

+1

+1 - Ładne, ale długie i chaotyczne. : dreszcze: Czy jestem w wyłożonej dębowymi panelami sali wykładowej ?! –

+1

hashing solone hasła nie jest tak naprawdę trudne do zrobienia. – Herbert

-2

Moja odpowiedź brzmi „nie rób tego”

Jest to bardzo złożone zagadnienie, pełne zabezpieczenia potencjalnych haczyka tych. Jeśli nie jesteś ekspertem w tej dziedzinie, to po prostu prosisz o kłopoty i problemy na drodze.

Polecam, patrząc na uzyskanie istniejącego rozwiązania do zrobienia. Niestety nie wiem, że byłbym szczęśliwy, polecając inne niż openid. Jestem pewien, że dostaniesz tutaj kilka dobrych sugestii ...

4

Zend Framework ma numer 'Auth' module, który byłby dobrym miejscem do rozpoczęcia. Lub, jeśli Twoja witryna będzie zawierała instalacje WordPressa lub PHPBB, istnieją sposoby na wykorzystanie modułów uwierzytelniania tych technologii do logowania się na innych stronach witryny.

+0

Moduł Zend Auth nie rozwiązuje pytania OP.Ponadto przykłady wykorzystują wiele niepewnych praktyk. Podsumowując: Zend Auth to straszne bezpieczeństwo. – Jacco

+0

Niepewne? To narzędzie zależy od tego, jak go używasz; dbasz o przykłady/dyskusje o tym, jak jest niepewnie? Zend_Auth to istniejący moduł uwierzytelniający z historią, który jest przeciwieństwem "rolling your own", co było pierwotnym pytaniem; Jak to nie satysfakcjonuje? – MidnightLightning

+0

[Zaawansowane użycie według przykładu] (http://zendframework.com/manual/en/zend.auth.adapter.dbtable.html) używa MD5, wysyła hasło do bazy danych zamiast sprawdzać po stronie PHP (co może powoduje, że hasło pojawia się w dziennikach zapytań) itp. Rzeczą z Zendami jest to, że uważają się za ekspertów i ignorują komentarze. – Jacco

2

Jedną z rzeczy, na którą należy zwrócić uwagę przy próbie uwierzytelnienia, jest rzeczywisty cel.

Na przykład na SO używam mojego loginu google i to działa, ponieważ oni po prostu muszą wiedzieć, kim jestem i mogą zaufać, że Google ma pomysł. Tak więc, jeśli ten model będzie działał dla ciebie, spójrz na użycie OpenID, ponieważ istnieją na to różne narzędzia.

Jeśli musisz zrobić własne, będą różne testy, aby upewnić się, że są bezpieczne, w zależności od tego, jak bardzo chcesz być paranoikiem.

  • Nigdy nie ufaj niczego od użytkownika, chyba że użyłeś jakiejś ścisłej weryfikacji.
  • Użyj https, aby chronić hasło użytkownika, jesteś im tak wiele winien.

Skończę moją odpowiedź tutaj, gdy Thom wykonał fantastyczną odpowiedź.

0

przez Soulmerge:

myślę accepted answer in your other question stwierdza to całkiem dobrze. Hashuj hasła solą. Poza tym na warstwie transportowej są pewne propozycje zabezpieczeń:

  • Używaj https przy wysyłaniu haseł. Dzięki temu nikt nie może ich złapać na drucie (man-in-the-middle attack lub klient używa złego proxy)
  • Alternatywą jest zaszyfrowanie hasła przy użyciu javascriptu po przesłaniu formularza logowania. Dzięki temu hasło nigdy nie jest transportowane w postaci zwykłego tekstu. Powinieneś przywrócić wartość hashowaną z solą na serwerze. (md5($_POST['postedPwHash'] . $salt))
-1

dobra metoda do nieco zabezpieczenia transakcji klient-serwer (jeśli nie ssl jest dostępny) jest użycie klucza losowego jednorazową stworzyć unikalny hash z poświadczeniami, a następnie wysłać tylko, że wyjątkowy hash na serwerze. następnie serwer porównuje ten skrót z wygenerowanym hashem zamiast porównywać go z prawdziwymi danymi uwierzytelniającymi. zapewniłoby to dobrą obronę przed atakiem man-in-the-middle. wadą jest to, że w tym celu użytkownik musi mieć włączony JS (przynajmniej nie znam dobrej metody szyfrowania po stronie klienta danych bez niego). oznacza to, że będziesz potrzebować odpowiedniego zabezpieczenia, gdy go nie ma. możesz nawet utworzyć formularz w JS, aby upewnić się, że jest włączony.

this library to prosta biblioteka, którą napisałem raz, że robi procedurę, którą opisałem, choć prawdopodobnie wymaga pewnych ulepszeń.

Należy pamiętać, że jest to dodatek do metod "solenia" i innych środków bezpieczeństwa po stronie serwera. jest również bardzo podatny na ataki słownikowe, ponieważ cały proces mieszania jest z definicji proceduralny, przewidywalny i widoczny dla użytkownika (jak zawsze JS).

Powiązane problemy