Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [php] Losowy ciąg znaków, Dlaczego tak, a nie inaczej?
MacDada
post
Post #1





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 24.06.2010
Skąd: Sopot

Ostrzeżenie: (0%)
-----


Hej!

Piszę właśnie mechanizm logowania. Po przeczytaniu wielu wątków na tym forum i pogoogle'owaniu tematu postanowiłem „posolić” hasła w bazie. Wykorzystuję do tego taką funkcję:

  1. function hashPasswd($passwd)
  2. {
  3. $salt = substr(md5(microtime() . substr($passwd, 1, 3)), 0, 32-strlen($passwd));
  4. return array('passwd' => MD5($passwd.$salt), 'salt' => $salt);
  5. }


Szybkie objaśnienie: użytkownik może dać hasło maksymalnie 20-znakowe, ale znając życie będzie ono w stylu „dupa”, więc banalne do odgadnięcia przy użyciu tęczowych tablic. Tak więc biorę aktualny czas jako rzecz w jakimś tam stopniu losową, doklejam 3 litery oryginalnego hasła, haszuję przy pomocy MD5 i ucinam wynik do tylu znaków, ile brakuje hasłu użytkownika do 32 znaków.
W ten sposób powstaje sól, którą doklejam do hasła, które użytkownik podał i dopiero „standardowo” haszuję, by wstawić do bazy.


Podobne rozwiązania widziałem wcześniej w w wielu innych skryptach przy tworzeniu soli czy losowych danych do własnego mechanizmu sesji.
No właśnie, LOSOWYCH. Jeśli generujemy losowe dane, to dlaczego tak często widzę użycie funkcji microtime() zamiast po prostu rand()? Z tego co podaje Wikipedia bardzo dobrze do tego nadaje się linuksowy /dev/random, który śledzi sprzętowe odchylenia, żeby generować losowe liczby - czy można z /dev/random skorzystać w skrypcie php?

Wiem, że nie tworzę skryptu dla NASA czy CIA, ale jeśli mamy do dyspozycji „lepsze” i „gorsze” rozwiązania, to chyba warto wiedzieć takie rzeczy i z nich korzystać...

A jak przy okazji macie jakieś sugestie do mojego mechanizmu „solenia”, to chętnie wysłucham (IMG:style_emoticons/default/winksmiley.jpg) Tylko, żeby to nie przerodziło się w świętą wojnę, czy w ogóle warto solić - poczytałem argumenty obu stron i przy samej idei „solenia” pozostanę (IMG:style_emoticons/default/winksmiley.jpg)

pozdr.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 15)
outsider
post
Post #2





Grupa: Zarejestrowani
Postów: 267
Pomógł: 36
Dołączył: 8.08.2008

Ostrzeżenie: (0%)
-----


po co az tak kombinowa z ta sola ? Wedlug mnie wystarcz md5($pass.'m&kiv$gh@e'); (IMG:style_emoticons/default/smile.gif) Haslo jest bezpieczne, w Twoim i moim przykladzie, tak samo. Przy konflikcie i tak Ci sol nie pomoze...
Go to the top of the page
+Quote Post
piotr94
post
Post #3





Grupa: Zarejestrowani
Postów: 331
Pomógł: 30
Dołączył: 11.11.2008
Skąd: Kraków

Ostrzeżenie: (0%)
-----


rand(0,999999); wyrzuca Ci liczbę losową z zakresu 0-999999 czyli masz teoretyczne prawdopodobieństwo 1:10^12, że liczba Ci się powtórzy, zakładając, że rand(); zwraca losowe wartości (wiadomo, że to funkcja pseudolosowa). tymczasem użycie microtime(); czerpie z aktualnego czasu, i nie ma niebezpieczeństwa, że Ci się powtórzy (chyba, że będziesz miał wehikuł czasu, lub zmienią czas na serwerze)
ot dlaczego
Go to the top of the page
+Quote Post
tehaha
post
Post #4





Grupa: Zarejestrowani
Postów: 1 748
Pomógł: 388
Dołączył: 21.08.2009
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


czy mi się wydaję czy Ty chcesz dla każdego hasła wygenerować losową sól i trzymać ją w bazie razem z hasłem?
Go to the top of the page
+Quote Post
everth
post
Post #5





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

Ostrzeżenie: (0%)
-----


Ja używam czegoś takiego:
  1. function getRandomPrefix($length=6) {
  2. $rand_string = str_ireplace('\"','',base64_encode(mt_rand()));
  3. $result = substr($rand_string,0,$length);
  4. if (strlen($result)<$length) {
  5. $result .= getRandomPrefix();
  6. $result = substr($rand_string,0,$length);
  7. }
  8. return $result;
  9. }


Powyższe generuje według mnie słabą sól (jest to jednak jedyna metoda jakiej używam pod PHP). Zazwyczaj używam statycznej soli - dynamicznie generowania to dla mnie strata czasu i zasobów (a hasło 'dupa' jest do złamania w ciągu kilku minut/godzin za pomocą ataku słownikowego), pod linuxem możesz uzyskać fajne ciągi za pomocą konsoli:
Kod
cat /dev/urandom | head -n "preferowana długość ciągu" | strings | tr -d '\n\t' | tr -d '\"'

I przede wszystkim nigdy nie używam do haszowania funkcji md5 - jeśli mogę użyć funkcji hash() to używam jej z parametrem sha512, w przeciwnym wypadku używam sha1, znacznie bezpieczniejsza od md5 i wydajnościowo niewiele gorsza. md5 obecnie nadaje się tylko do tworzenia identyfikatorów (np. kluczy w bazach danych)

Ten post edytował everth 21.07.2010, 15:34:05
Go to the top of the page
+Quote Post
ADeM
post
Post #6





Grupa: Zarejestrowani
Postów: 455
Pomógł: 69
Dołączył: 23.10.2004
Skąd: Oświęcim

Ostrzeżenie: (0%)
-----


~Tehaha zadał już bardzo ważne pytanie... Chcecie generować inną sól dla każdego użytkownika?
Go to the top of the page
+Quote Post
MacDada
post
Post #7





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 24.06.2010
Skąd: Sopot

Ostrzeżenie: (0%)
-----


Tak, chcę wygenerować różną sól dla każdego z użytkowników.
Go to the top of the page
+Quote Post
ADeM
post
Post #8





Grupa: Zarejestrowani
Postów: 455
Pomógł: 69
Dołączył: 23.10.2004
Skąd: Oświęcim

Ostrzeżenie: (0%)
-----


I będziesz to trzymał w bazie obok hasła?
Go to the top of the page
+Quote Post
MacDada
post
Post #9





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 24.06.2010
Skąd: Sopot

Ostrzeżenie: (0%)
-----


tak mam to teraz zrobione

Kilka schematów ataku…

Poziom 1:
Za pomocą SQL-Injection ktoś uzyskał dostęp do bazy danych. Jeśli hasła są widoczne to po zabawie. Stąd minimum to ich haszowanie.

Poziom 2:
Jeśli użyję MD5 lub innego powszechnego algorytmu to napastnik może użyć tęczowych tablic, żeby uzyskać prawidłowe hasło. Więc hasło musi być albo odpowiednio skomplikowane, żeby za pomocą tablic go nie znaleźć albo mogę do każdego hasła dokleić coś co sprawi, że tablice (raczej) staną się bezużyteczne. Powstaje więc sól.

Poziom 3:
Napastnik ma dostęp do kodu źródłowego skrypu i tym samym poznaje sól. Wystarczy więc, że ma listę popularnych haseł, podokleja do nich sól i przehaszuje je, żeby dostać hasło. Można mu jednak utrudnić pracę…

Poziom 4:
Tym utrudnieniem będzie różna sól dla każdego hasła. Zresztą, mechanizm utworzenia soli nie będzie publiczny, więc za pomocą security through obscurity mamy dodatkowe zabezpieczenie…
Go to the top of the page
+Quote Post
ADeM
post
Post #10





Grupa: Zarejestrowani
Postów: 455
Pomógł: 69
Dołączył: 23.10.2004
Skąd: Oświęcim

Ostrzeżenie: (0%)
-----


Ale przecież skoro uzyskał dostęp do bazy i haseł, to ma także dostęp do soli...

Ten post edytował ADeM 21.07.2010, 17:56:25
Go to the top of the page
+Quote Post
MacDada
post
Post #11





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 24.06.2010
Skąd: Sopot

Ostrzeżenie: (0%)
-----


Stąd punkt 3 i 4 - musi mieć jeszcze dostęp do plików, żeby poznać mechanizm powstawania soli, a ponieważ sól jest różna bruteforce na zasadzie przeklejania soli haszowania, itd. zajmie dużo więcej czasu (może być niemożliwy lub się nie opłacać).

Ten post edytował MacDada 21.07.2010, 18:07:32
Go to the top of the page
+Quote Post
tehaha
post
Post #12





Grupa: Zarejestrowani
Postów: 1 748
Pomógł: 388
Dołączył: 21.08.2009
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


1. w moim przekonaniu sól ma utrudnić deszyfrowanie haseł, w momencie kiedy nie powołana osoba dostanie się do bazy, stąd trzymanie soli w bazie jest bez sensu.
2. Twój "poziom 3" też nie ma sensu, przecież jak ktoś już ma dostęp do ftp to sobie może zrobić co chce, więc ta sól w bazie niczego nie utrudnia.
Generalnie moim zdaniem sól w bazie nie stanowi żadnego zabezpieczenia, a jedynie Tobie utrudnia życie

@up jak masz dostęp do pliku, to po co masz poznawać jakiś mechanizm powstawania soli, skoro sobie możesz od razu ustawić sesje i się zalogować jako dowolny user z dowolnymi uprawnieniami

Ten post edytował tehaha 21.07.2010, 18:12:37
Go to the top of the page
+Quote Post
ADeM
post
Post #13





Grupa: Zarejestrowani
Postów: 455
Pomógł: 69
Dołączył: 23.10.2004
Skąd: Oświęcim

Ostrzeżenie: (0%)
-----


~Tehaha mądrze prawi :]
Zresztą... Popatrz na Twoje przypadki, które rozważałeś.

1:
Ktoś ma dostęp do bazy (hasła + sole), nie ma jednak dostępu do kodu źródłowego.
W tym momencie nie wie tylko jak doczepiana jest sół do hasła.
Gdyby sól była w kodzie, to w ogóle by nie wiedział jaka ona jest i jak jest doczepiana.

2:
Ktoś ma dostęp do źródeł... W tym momencie chyba bez problemu znajdzie sobię dane do bazy (co daje dostęp do soli, haseł...) i informacje jak doczepiać sól.
Go to the top of the page
+Quote Post
tehaha
post
Post #14





Grupa: Zarejestrowani
Postów: 1 748
Pomógł: 388
Dołączył: 21.08.2009
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


no rzeczywiście rozpatrując Twój Poziom 1, to:
- jeżeli mam dostęp do bazy i znam sól to ciągu 3min wygeneruje sobie nowe hasło korzystając z tej soli, sposób haszowania hasła to w 99,9% przypadków md5() lub sha1(), więc sprawa prosta, wstawiam nowe hasło do bazy i się loguje.
Czyli jak sam niestety widzisz to dodatkowe zabezpieczenie jest de facto luką w zabezpieczeniach, bo pozwala osobie z dostępem do bazy na wygenerowanie i wstawienie swojego hasła, co nie było by możliwe gdyby sól była zapisana w pliku php
Go to the top of the page
+Quote Post
wywrot4
post
Post #15





Grupa: Zarejestrowani
Postów: 18
Pomógł: 9
Dołączył: 8.10.2009
Skąd: Tarnów

Ostrzeżenie: (0%)
-----


Wydaje mi się że nie rozumiecie idei solenia haseł, polecam przeczytać artykuł Hashowanie haseł z solą, a dla opornych obowiązkowo komentarze
Go to the top of the page
+Quote Post
everth
post
Post #16





Grupa: Zarejestrowani
Postów: 782
Pomógł: 153
Dołączył: 21.07.2010

Ostrzeżenie: (0%)
-----


@wywrot4 - artykuł fajny, jednak dalej nie widzę sensu by dodawać sól w bazie danych. Z jednego powodu - o wiele łatwiej jest według mnie uzyskać dostęp do bazy niż do skryptu. Ktoś tam sensownie napisał że to likwiduje dodatkowe zabezpieczenie w postaci nieznajomości ciągu soli. Jeśli znamy hash hasła to na 99% poznamy też sól.
Na upartego można napisać algorytm generujący sól z danych w bazie - ale bez zaznaczania z których i w jakiej kolejności (ktoś się tam tak wypowiedział i ja też tak robię). To wszystko jednak można o kant d*py potłuc jak stosuje się hashowanie md5 - znalezienie kolizji dla takiego hashu to kilkanaście godzin - może dla amatorskich programów to bez znaczenia, ale jak ktoś stawia komercyjny projekt to trzeba brać to pod uwagę.
Czyli można zrobić tak:
  1. Hasło co najmniej 8 znaków
  2. login+hasło (kolejność złączenia dowolna)
  3. + statyczna sól umieszczona w kodzie (dla mnie 128 znaków)
  4. + dodatkowo zmienna sól generowana z bazy danych (ale nie zapisywana jako osobne pole w bazie)
  5. Zastosowanie dobrej funkcji skrótu


Można wymyślić bardziej paranoiczne rozwiązania jednak powyższe na pewno oprze atakom za pomocą tęczowych tablic i nie tak łatwo da się złamać za pomocą znalezienia kolizji.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.08.2025 - 02:40