Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mysql] kodowanie hasła
Forum PHP.pl > Forum > Przedszkole
Chemiq
mam system rejestracji i logowania. jest w nim zapisywanie zakodowanego hasła i działa jak należy. problem zaczyna się gdy trzeba się zalogować. przyjrzałem się problemowi i doszedłem do wniosku że hasło mimo wszystko nie jest rozkodowywane. oto kod odpowiadający za odczytywanie zakodowanego hasła:
  1. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo')";
  2. $result = mysql_query($sql);

jak przy logowaniu wstawie zamiast normalego hasła to zakodowane to można się zalogować.
rama
Hmm, funkcja password() z MySQL działa tylko w jednym kierunku (wyłącznie szyfruje).
Cytat(Manual SQL)
PASSWORD() encryption is one-way (not reversible).
Jednakże, aby porównać hasło z tym którym znajduje się w bazie możesz spróbować użyć również tej funkcji password() do zakodowania "plain password".

Przykład (koncept):
  1. <?php
  2. /**
  3.  * $passwd to hasło do zakodowania
  4.  */
  5. $passwd = 'test';
  6.  
  7. $mo = mysql_connect( 'server', 'user', 'pass' );
  8. $ms = mysql_select_db( 'db' );
  9. $pr = mysql_query( "SELECT PASSWORD( '$passwd' ) as password" );
  10.  
  11. /**
  12.  * W zmiennej $row znajduje się hasło wygenerowane przez funkcję
  13.  * mysql password() 
  14.  */
  15. $row = mysql_result( $pr, 'password' );
  16.  
  17.  print '<pre>' . print_r( $row, true ) . '</pre>';
  18.  
  19. mysql_close( $mo );
  20. ?>
mariuszn3
Jeśli podajesz mu zakodowane hasło to nie korzystaj już z funkcji PASSWORD, ona koduje hasło.. czyli w efekcie masz ponownie zakodowany ciąg znaków, który był już kodem. Hasła w bazie są zapisywane w zakodowanej formie.. więc po prostu bezpośrednio porównaj zakodowaną wersję (haslo = '$haslo') i powinno zadziałać.
rama
Zgadzam się, iż hasła użytkowników w MySQL są standardowo szyfrowane przez użyciu funkcji password(). Jednakże, może źle zrozumiałem post autora, ponieważ sądzę, że autor postu miał na myśli swój własny system autoryzacji użytkowników, inaczej mówiąc, system logowania, gdzie hasła w postaci zaszyfrowanej przy użyciu funkcji mysql password() znajdują się już w jakiejś tam tabeli. Jak dobrze pewnie wiesz, to chyba nie istnieje żadna funkcja w php, która koduje ciąg (string) w ten sam sposób, co password() w MySQL.

(Podkreślam) Dlatego założyłem, że autor posiada hasła w bazie w postaci zakodowanej i wysyła hasło (do porównania) przez formularz w postaci czystego tekstu (tzw. plain password). Przykładowy skrypt (koncept) napisałem pod kątem w/w przemyśleń, który zarazem umożliwia zwrócenie ciągu (string) w postaci zaszyfrowanej przez użycie password() i dalej daje możliwość autorowi do porównania obu tych wartości haseł.

PS Jeśli źle zrozumiałem sens problemu, to przepraszam winksmiley.jpg
@edit
PS1 Owy skrypt służy do zakodowania czystego hasła (sam tekst) przy użyciu funkcji mysql password().
mariuszn3
-> rama. Jak wysłałem swoją odpowiedź jeszcze nie widziałem Twojej. Moja była bezpośrednią odpowiedzią na post autora.. z którego po prostu wywnioskowałem, że (z nie wskazanej przyczyny) autor próbuje porównać hasło już zakodowane i dlatego zapytania zwraca mu to czego oczekuje tylko wtedy jeśli je rozkoduje i ponownie zakoduje poprzez PASSWORD.
O tym, że tylko MySQL może ponownie zakodować hasło tak samo (poprzez PASSWORD) nie wiedziałem.. i faktycznie (zajrzałem do google) wyglada na to, że tak jest.. czyli trzeba by zapytać autora czym kodowane były hasła które są w bazie i czym kodowane hasło daje do porównania.. jeśli wszystko dobrze zrozumiałem smile.gif
rama
@mariuszn3
Spoko, nie gniewam się winksmiley.jpg

@ogólnie
Tak sobie myślę, że autor "wykombinował" to tak:
Skrypt rejestracji -> password('haslo') do bazy
Skrypt logowania -> password('haslo') z bazy

Zapominając o tym, jak już wcześniej wspominałem, że funkcja mysql password() działa tylko w jednym kierunku, czyli wyłącznie szyfruje smile.gif
Chemiq
myślałem dokładnie tak jak rama w ostatnim poście napisał rama. jeżeli dobrze rozumuję to muszę najpierw zakodować wpisane hasło i porównać z tym które jest w bazie ale nie mam pojęcia jak to zrobić. nie wiem jak wstawić skrypt który napisał rama do swojego. oto fragment w którym należy coś dodać ale właśnie nie wiem co:
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg"); 
  6.  
  7. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = '$haslo'"; 
  8. $result = mysql_query($sql);
  9. ?>
mariuszn3
Rozumiem, że hasło pobrane z formularza jest w swojej pierwotne formie w zmiennej $_SESSION['haslo'].
Wtedy poniższe powinno jak najbardziej zadziałać.
  1. SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo')
Chemiq
nie może zadziałać bo PASSWORD() działa tylko przy kodowaniu. nie da się w ten sposób rozkodować tego hasła (a nawet jak się da to i tak nie dzała bo tak pierwotnie próbowałem). zmienna $haslo pobierana jest jako zakodowana.
mariuszn3
Cytat(Chemiq @ 4.08.2006, 15:53 ) *
nie może zadziałać bo PASSWORD() działa tylko przy kodowaniu. nie da się w ten sposób rozkodować tego hasła (a nawet jak się da to i tak nie dzała bo tak pierwotnie próbowałem). zmienna $haslo pobierana jest jako zakodowana.

To w takim razie musisz odkodować wpierw hasło.. czym (jakim algorytmem) i w którym momencie zakodowane jest to hasło?
Chemiq
właśnie od samego początku chodzi mi o odblokowanie tego hasła. jest ono zakodowane od momentu rejestracji.
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo_wpisane; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg"); 
  6.  
  7. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = '$haslo'"; // tutaj jest pobierane ZAKODOWANE hasło
  8. $result = mysql_query($sql);
  9. ?>

może tak będzie łatwiej:
1. zmienna $haslo_wpisane to NIEZAKODOWANA wartość wpisana przez użytkownika w formularzu
2. zmienna $haslo to ZAKODOWANE hasło (zostało zakodowane przy rejestracji użytkownika poprzez funkcję PASSWORD) pobrane z bazy danych
mariuszn3
Cytat(Chemiq @ 4.08.2006, 16:17 ) *
właśnie od samego początku chodzi mi o odblokowanie tego hasła. jest ono zakodowane od momentu rejestracji.
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo_wpisane; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg"); 
  6.  
  7. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = '$haslo'"; // tutaj jest pobierane ZAKODOWANE hasło
  8. $result = mysql_query($sql);
  9. ?>

może tak będzie łatwiej:
1. zmienna $haslo_wpisane to NIEZAKODOWANA wartość wpisana przez użytkownika w formularzu
2. zmienna $haslo to ZAKODOWANE hasło (zostało zakodowane przy rejestracji użytkownika poprzez funkcję PASSWORD) pobrane z bazy danych

No dobrze.. ale jaki jest Twój cel.. z tego co wcześniej pisałeś rozumiem, że chcesz poprostu autoryzować dane wpisane przez użytkownika do formularza i albo go zalogować albo nie (jeśli podał nie właściwe dane).

Natomiast powyżej piszesz jakieś sprzeczne rzeczy.. Twoje zapytanie wcale nie pobiera zakodowanego hasła do zmiennej hasło.. sprawdź dokładnie jaka jest konstrukcja zapytania SELECT.. to co wpisuje się po WHERE to już tylko dyktowanie warunków jakie muszą spełniać dane, które chcesz wyciągnąć z bazy.

Najprawdopodobniej chodzi Ci o coś takiego:
  1. SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo_wpisane')

Powyższe zapytanie zwróci Ci wszystkie rzędy z tabeli użytkownik, które będę miały pola login i haslo odpowiadające wartościom wpisanym w formularzu.
Chemiq
źle się rozumiemy. hasło JUŻ W BAZIE DANYCH JEST ZAKODOWANE, więc do zmiennej $haslo jest pobierane jako ciąg znaków (czyli jakiś kod). wpisanie:
  1. SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo_wpisane')

powoduje iż jest błąd logowania gdyż hasła się nie zgadzają. gdy wstawię hasło zakodowane (skopiowane z bazy danych) to mogę się normalnie zalogować
mariuszn3
Cytat(Chemiq @ 4.08.2006, 16:47 ) *
źle się rozumiemy. hasło JUŻ W BAZIE DANYCH JEST ZAKODOWANE, więc do zmiennej $haslo jest pobierane jako ciąg znaków (czyli jakiś kod). wpisanie:
  1. SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo_wpisane')

powoduje iż jest błąd logowania gdyż hasła się nie zgadzają. gdy wstawię hasło zakodowane (skopiowane z bazy danych) to mogę się normalnie zalogować

Pierwsza rzecz.. funkcja PASSWORD koduje ciąg znaków do hash'a (nie działa w drugą stronę!) .. tak więc porównanie w WHERE haslo = PASSWORD('$haslo_wpisane') jak najbardziej porównuje dwa hash'e i zakładając, że hasło, które jest bazie, zostało dodane w postaci hasha wygenerowanego za pomocą tej samej funkcji PASSWORD() walidacja powinna przebiegać poprawnie.
rama
Heh, nie było mnie pare godzin i już jakieś nieporozumienia, ano śmiem tak twierdzić, bo mam dobry humor, ale do rzeczy winksmiley.jpg

Spróbuję ogólnie wyjaśnić o co chodzi w tym problemie, bo zrozumiałem całą tą ideologię (czytać koncept) autora i nie chce się powtarzać, by później przejść do konkretów, czyli integracji mego skryptu (wcześniej napisanego) z systemem logowania autora, czy tam autoryzacji, jak zwał tak zwał smile.gif

Idea mechanizmu autoryzacji smile.gif
a ) Użytkownik rejestruje się na specjalnej stronie (np. rejestracja.php), gdzie wprowadza hasło w postaci niezakodowanej, czyli sam tekst, i po potwierdzeniu wszystkie dane zapisywane są w bazie danych (jakieś tam tabelce), gdzie owe hasło przyjmuje postać zaszyfrowaną (password())

b ) User chcąc zalogować się na stronie wprowadza hasło do formularza w postaci niezakodowanej (plain password = 'czytelny tekst').

c ) (Mechanizm skryptu logowania)
- wprowadzenie hasła (niezakodowanego) z sesji do zmiennej $haslo
- skrypt pobiera hasło (zakodowane) z bazy
* zaszyfrowanie hasła (niezakodowanego) z formularza
* porównanie haseł (hasło z bazy = haslo z formularza)

Legend:
* - element oznaczony tym symbolem jest brakującym "ogniwem" w systemie autoryzacji.


Zintegrowanie:
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg");
  6.  
  7. $pr = mysql_query( "SELECT PASSWORD( '$haslo' ) as password" );
  8. $haslo = mysql_result( $pr, 'password' );
  9.  
  10. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = '$haslo'"; 
  11. $result = mysql_query($sql);
  12. ?>
lub jak to wcześniej napisał (bodajże) mariuszn3
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg");
  6.  
  7. $sql = "SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD( '$haslo' )"; 
  8. $result = mysql_query($sql);
  9. ?>
Też powinno działać, bo jak nie patrzeć są to dwie metody uzyskania tego samego efektu...

@edit
Tak sobie myśle, czy nie lepiej byłoby, aby php zajmowało się weryfikacją użytkownika?
  1. <?php
  2. $_SESSION['login'] = $login; //wartość pobrana z pola login w formularzu
  3. $_SESSION['haslo'] = $haslo; //wartość pobrana z pola haslo w formularzu
  4.  
  5. dbConnect("yugiohrpg");
  6.  
  7. $pr = mysql_query( "SELECT PASSWORD( '$haslo' ) as password" );
  8. $pass = mysql_result( $pr, 'password' );
  9.  
  10. $mq = mysql_query( "SELECT * FROM `uzytkownik` WHERE login = '$login'" );
  11.  
  12. if( mysql_num_rows( $mq ) === 1 ) 
  13. {
  14.  $userdata = mysql_fetch_assoc( $mq );
  15.  
  16.  if( $userdata['haslo'] === $pass ) 
  17.  {
  18. /**
  19.  * tutaj co ma robić po poprawnej autoryzacji
  20.  * np. przekierowanie na inna strone
  21.  */
  22.  } else {
  23. print 'Złe hasło';
  24.  }
  25.  
  26. } else {
  27.  print 'Nie ma takiego użytkownika';
  28. }
  29. ?>


PS Zakładając, że nazwy użytkownika są jakoś limitowane (np. wyłącznie z małej litery cały string) smile.gif
mariuszn3
a nie lepiej wszystko załatwić za pomocą jednego zapytania? :
  1. SELECT * FROM `uzytkownik` WHERE login = '$login' AND haslo = PASSWORD('$haslo')

wyjdzie przecież na to samo i będzie nawet trochę wydajniej smile.gif
rama
Racja, również to zauważyłem, gdy edytowałem mój post ( odrazu po dodaniu i późniejszych drobnych poprawkach ). Ale nadal mnie ciekawi czy obie te metody działają poprawnie u autora, bo być może autor wprowadza inne hasło do formularza do logowania niż te które znajduje się w bazie (inna strona kodowa, jeśli używane są polskie znaki w haśle)?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.