Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: podwójne hashowanie haseł
Forum PHP.pl > Forum > PHP
Stron: 1, 2, 3
viking
Już od kilku lat istnieje taki malutki projekcik http://www.openwall.com/phpass/ i chyba staje się coraz popularniejszy bo więcej darmowych skryptów zaczyna z niego korzystać (drupal, WP, ajkieś fora). Osobiście już dawno porzuciłem własne pomysły na rzecz tego. Najsilniejsza metoda to blowfish a ta z kolei według różnych testów jest też bardzo szybka. A i tak na nic nasze starania jeśli user trzyma hasło przypięte do monitora.
Kocurro
Ja zawsze używam następującej metody i jak do tej pory nikomu się nie udało włamać.

W bazie trzymam następujące informacje o haśle:

MD5 z hasła
SHA1 z hasła
długość hasła

i oczywiście mam jeszcze użytą sól do zabiegów MD5 i SHA1, która jest generowana na podstawie informacji: id użytkownika, login użytkownika, data rejestracji (czyli tych danych, które są niezmienne).

Żeby umilić życie te trzy wartości mam zapisane odpowiednio w jednym ciągu. Na niektórych serwisach rezygnuję z użycia SHA1 ponieważ jak do tej pory MD5 z długością hasła dawało skuteczną ochronę.

Oprócz tego kody źródłowe, które są na serwerze są zakodowane więc nie jest łatwo rozpoznać jak dokładnie jest tworzone hasło. Sama zawartość bazy danych niestety niewiele pomoże. Aha - wspominałem już o tym, że wartości wpisywane do bazy o użytkowniku takie jak dane osobowe są zaszyfrowane a klucz szyfrujący/odszyfrujący znajduje się w zakodowanym kodzie źródłowym.

Wiem, że moja metody jest mniej skuteczna niż wielokrotne MD5 haseł ... ale muszę jakoś sobie radzić winksmiley.jpg

Pozdrawiam,
Łukasz
yevaud
Często w tym wątku pojawia się problem szybkości algorytmu hashowania. Martwicie się, że algorytm będzie wolny, cieszycie się gdy md5 jest superszybkie. Wydaje mi się, że to podstawowy błąd na poziomie założen. Funkcje hashujące których używamy - i nie ważne czy będzie to md5, czy coś z rodziny sha2, albo nawet cos bardziej ekscentrycznego jak haval - nie zostały zaprojektowane do szyfrowania kilku/kilkunasto znakowych haseł, a do hashowania dużych bloków danych, lub do hashowania duzych ilości skrótów w bardzo krótkim czasie(np. podczas sortowania, lub w implementacji protokołu sieciowego). One naprawde SĄ szybkie:)

W przypadku haseł w serwisie webowym, operacja hashowania wykonywana jest tylko raz na każde logowanie, więc nie musi być bardzo szybka. Różnice zajętości ramu podczas obliczeń na poziomie kilu kb także nie są tutaj problemem. Dodatkowo np. obliczanie hasha nie powinno dać się zrównoleglić. Można pewnie wymienić jeszcze kilka założeń które będą prawdziwe dla haseł serwisu webowego, a niekoniecznie prawdziwe przy innych zastosowaniach.

Popatrzmy w jaki sposób można zaatakować hash w serwisie webowym:

a) brute-force. Najbardziej rozpowszechniona i najłatwiejsza metoda ataku.
Problemem jest bardzo duża szybkość komputerów. Atakujący może wygenerować olbrzymie ilości hashów w krótkim czasie. Dodatkowo niezabezpieczony formularz logowania może pozwalać na wielokrotne logowania w krótkim czasie. Za kilkaset $/h można wynając superkomputer obliczający 500,000,000,000 hashy na sekundę!

cool.gif slownik/brute-force
Problemem jest mała inwencja użytkowników przy wymyślaniu haseł

c) rainbow
Problemem jest generalnie brak "soli" smile.gif Atakujący ma wygenerowany słownik hashy

d) analiza różnicowa i inne metody matematyczne
W typowym serwisie webowym nie jest to problem, jednak warto pamiętać, że md5(md5($val)) będzie miało prawdopodobnie gorsze właściwości, niż pojedyńcze użycie funkcji hashującej, dlatego należy raczej unikać takiego rozwiązania. Problem wielokrotnego hashowania typu md5(md5(md5(...) leży prymitywnym sposobie podawania danych do funkcji -> tylko za pierwszym razem używamy całości dostępnych danych, za każdym następnym razem do funkcji hashującej wchodzą zawsze dokladnie 32 znaki, a większość "losowości" która tkwiła w oryginalnym haśle, jest (prawdopdobnie) powoli tracona przez funkcje mieszającą. Piszę prawdopodobnie bo nie udało się udowodnić do tej pory ani że jest tracona ani że nie jest, można jednak dość bezpiecznie założyć, że stałe 32 znaki poddawane cały czas temu samemu algorytmowi, maja raczej gorsze właściwości niż losowy ciąg znaków smile.gif

e) atak DOS
W przypadku serwisu webowego, atak na kolizję przy logowaniu nie ma za bardzo sensu, ale jeśli operacja hashowania jest kosztowna, można doprowadzić do wyczerpania zasobów serwera np. poprzez wielokrotne logownie.


Teraz remedium na nasze problemy:
e) ograniczenie ilości logowań, albo szybka funkcja hashująca
d) używanie całości danych wejściowych przy każdej iteracji algorytmu hashującego, używanie matematycznie poprawnych funkcji hashujących
c) sól.
cool.gif Słownik i odrzucanie idiotycznych haseł użytkowników. Narzucenie odpowiedniego poziomu skomplikowania na hasła.
a) Wolny algorytm hashowania! przez wolny, rozumiem np. ~10ms

No włąsnie, jak widać na końcu szybki algorytm hashujący, jest tak naprawde WADĄ w przypadku typowego serwisu webowego.

Po tym przydlugim wstępie, przejdę do sedna:
http://en.wikipedia.org/wiki/Bcrypt - nie mylić z http://bcrypt.sourceforge.net/
jest to algorytm który spełnia założenia które sobie postawiliśmy. Jest matematycznie poprawny, oparty na sboxach z blowfisha, a do tego można sterować jego złożonością tak żęby osiągnąć wymaganą szybkość(a raczej wolność). Niewielka modyfikacja w szybkości funkcji hashującej i atakujący który próbuje bruteforce potrzebuje nagle lat zamiast minut na złamanie haseł, a dla naszego serwisu różnica rzędu paru ms przy logowaniu nie jest zauważalna.

http://stackoverflow.com/questions/4795385...asswords-in-php

Podsumowując:
1. wolna, poprawna matematycznie funkcja hashująca typu bcrypt
2. słownik
3. ograniczenie ilości logowań
4. sól
sobol6803
Witam. Wiem, że tu bardziej chodzi o hash haseł, ale ja mam pytanie o przenoszenie hash'a między serwerami. Np. jeśli w hashu chcemy przenieść 3 zmienne:

Kod
$id = 1;
$imie = 'andrzej';
$nazw = 'kowalski';


I chcę to przenieść na inny serwer, aby wykorzystać w formularzu w postaci tajnej:

Kod
$hash = md5($id.$imie.$nazw);


Dodaje do url'a i przechwytuję na inym serwerze w postaci:

example.com/form.php?hash=9812asd65017578gs23487 (liczby przypadkowe z klawiatury, jednak to jest ten wygenerowany hash).

Teraz chciałbym wpisać te 3 zmienne zakodowane w hashu do formularza. Jak to zrobić?

Z góry dzięki za pomoc smile.gif

Pozdrawiam.

PS. Sorry za odkopanie, ale nie chciałem specjalnie nowego tematu zakładać.
Leihto
Jeśli chcesz mieć zdekodowane te dane to tak się nie da (a raczej Ty tego nie zrobisz).
jeśli ma to być hash wpisany w input to proszę:
  1. <!-- Link : example.com/form.php?hash=9812asd65017578gs23487 -->
  2. <form action="" method="POST">
  3. <input type="text" value="<?php $_GET['hash']; ?>">
  4. </form>


Podstawy podstawy podstawy!
Amedos
A co myślicie by zrobić własne hashowanie ?
Funkcja str_replace
erix
A czy przeczytałeś w ogóle ten temat...?
mrWodoo
Najlepiej używać bcrypt, bo możemy dostosować 'trudność obliczeń' tzw. rundy, 12 rund tak zwolni prędkość ataku brute-force... że sobie to odpuszczą chyba, że to hasło do biur CIA / FBI smile.gif

http://www.codinghorror.com/blog/2012/04/speed-hashing.html


Bcrypt: php manual -> crypt
amii
W manulau nie zalecają stosowania md5, sha1, sha256 do heszowania ze względu na zbyt dużą szybkość i możliwy atak brute force. Mam dwa pytania:
1. Czy md5, sha1 i sha256 itp. mogą wygenerwać dwa lub więcej takich samych kluczy dla różnych danych wejściowych ? Przypuszczam, że tak bo inaczej taki algorytm byłby doskonałym archiwizerem. W dokumntacji algorytmu md5 -> http://www.faqs.org/rfcs/rfc1321.html znalałem jednak coś takiego:
Cytat
It is conjectured that it is computationally infeasible to produce
two messages having the same message digest, or to produce any
message having a given prespecified target message digest.

Więc jak to jest ?
2. Wbudowane opóźnienie można osiągnąć za pomocą funckji crypt gdzie określamy algorytm, sól i ilość iteracji (to jest wbudowane opóźnienie). Tyle, że funkcja crypt nie obsługiwana przez silnik bazy danych. Jeśli np. w Zend autoryzacja odbywa się przy pomocy Zend_Auth_Adapter_DbTable w ten sposób. To klasa wykorzystuje wbudowaną funcję silnika bazy danych czyli SHA1 i CONCAT
Jak uwierzytelnić za pomocą crypt ?
  1. $authAdapter = new Zend_Auth_Adapter_DbTable(
  2. Zend_Db_Table::getDefaultAdapter(),
  3. "users",
  4. "email",
  5. "md5",
  6. "SHA1(CONCAT('" . Zend_Registry::get('salt') . "', ?, salt))");
erix
Cytat
Czy md5, sha1 i sha256 itp. mogą wygenerwać dwa lub więcej takich samych kluczy dla różnych danych wejściowych ?

Tak, gdyż wynika to z dziedziny, w której są tworzone hashe. Jest ona znacznie bardziej ograniczona niż treść, którą można hashować.

Cytat
2. Wbudowane opóźnienie można osiągnąć za pomocą funckji crypt gdzie określamy algorytm, sól i ilość iteracji (to jest wbudowane opóźnienie). Tyle, że funkcja crypt nie obsługiwana przez silnik bazy danych. Jeśli np. w Zend autoryzacja odbywa się przy pomocy Zend_Auth_Adapter_DbTable w ten sposób. To klasa wykorzystuje wbudowaną funcję silnika bazy danych czyli SHA1 i CONCAT
Jak uwierzytelnić za pomocą crypt ?

Masz tu błędne założenie projektowe - PO CO obarczać bazę hashowaniem?
amii
To akurat nie moje założenie tak jest zaimplementowana metoda w zend framework, jakoś jednak przeżyje z sha1 + podwójna sól. No chyba, że ktoś na zend posługuje się crypt i byłby chętny opisać jak się za to zabrać
Neymar11
Zawsze offtopowałem ^^.
A do tematu:

Można zrobić coś takiego, myślę że to coś da
  1. <?
  2. $rand = rand(1,11);
  3. $dodatek = md5($rand);
  4. $haslo = 'megatajne123';
  5. $hashcalk = md5($rand, $haslo);
  6. echo $hashcalk;
  7. ?>

A output raw bardzo dziwny haha.gif:
y Z��o��~���
Nie wiem co to znaczyć ma, no ale myślę że hasło zahaszowane dobrze haha.gif Raczej te kilka bajtów ktoś by rozszyfrowywał z 10 lat hahahaha biggrin.gif
Forti
Cytat(Neymar11 @ 21.02.2015, 03:00:41 ) *
Zawsze offtopowałem ^^.
A do tematu:

Można zrobić coś takiego, myślę że to coś da
  1. <?
  2. $rand = rand(1,11);
  3. $dodatek = md5($rand);
  4. $haslo = 'megatajne123';
  5. $hashcalk = md5($rand, $haslo);
  6. echo $hashcalk;
  7. ?>

A output raw bardzo dziwny haha.gif:
y Z��o��~���
Nie wiem co to znaczyć ma, no ale myślę że hasło zahaszowane dobrze haha.gif Raczej te kilka bajtów ktoś by rozszyfrowywał z 10 lat hahahaha biggrin.gif



to niczym się nie różni jak zwykłe md5($haslo, $sól). Masz bcrypt od takich zadań.
Crozin
To na dobrą sprawę jest nic innego, jak
  1. md5(rand(1, 11), true);
To nawet skrót hasła nie jest i tylko przez idiotoodporność PHP-a błędami na lewo i prawo nie rzuca. Pod żadnym pozorem nie powinno się z czegoś takiego korzystać.
Neymar11
A ogarnijcie to:

  1. <?
  2. function hash($string) {
  3.  
  4. $hashe = array(
  5. "sha512","ripemd128","ripemd256","ripemd320","whirlpool",
  6. "tiger128,3","tiger160,3","tiger192,3","tiger128,4","tiger160,4",
  7. "tiger192,4","snefru","gost","adler32","crc32","crc32b");
  8. foreach($hashe as $hash) {
  9. hash($hash, $string);
  10. }
  11. return $string;
  12. }
  13. ?>


ma to sens? tongue.gif
wklejcie do notatnika, zincludujcie albo w tym samym pliku poza funkcja echo hash('string');
mysle ze cos da ^^ ciekawe, jak bardzo przedluza czas wykonania niz samo md5 tongue.gif
pyro
Cytat(Neymar11 @ 2.05.2015, 19:28:12 ) *
A ogarnijcie to:

  1. <?
  2. function hash($string) {
  3.  
  4. $hashe = array(
  5. "sha512","ripemd128","ripemd256","ripemd320","whirlpool",
  6. "tiger128,3","tiger160,3","tiger192,3","tiger128,4","tiger160,4",
  7. "tiger192,4","snefru","gost","adler32","crc32","crc32b");
  8. foreach($hashe as $hash) {
  9. hash($hash, $string);
  10. }
  11. return $string;
  12. }
  13. ?>


ma to sens? tongue.gif
wklejcie do notatnika, zincludujcie albo w tym samym pliku poza funkcja echo hash('string');
mysle ze cos da ^^ ciekawe, jak bardzo przedluza czas wykonania niz samo md5 tongue.gif


Nie ma:

Po 1: Bo infinite recursion

Po 2: Sam "tok myślenia" takiego kodu to pomysł delikatnie mówiąc wysoce nierozsądny
darek334
Cytat(nospor @ 23.03.2006, 08:34:33 ) *
Przyznam szczerze, iż nie wiem jak robi się w praktyce ataki b-f. Nigdy nie robilem wink.gif Wiem z teorii tylko jak dzialają.
Ale przypuśćmy, ze taki atak polega na ciąglym wysylaniu requesta do strony, gdzie należy się zalogować. W request wysylane jest haslo. Jak wiemy jest to haslo wówczas w postaci jawnej (nie hashowane). Tak więc nie ma znaczenia, ze hash będzie mial 32 bajty czy też więcej. Nie ma znaczenia, ze po stronie serwera bedzi dodawany jakiś tajny ciąg do tego. Znaczenie ma to, ze haslo ma 8 znaków i wygenerowanie ich wszystkich kombinacji nie ma już zadnego związku z metodami hashowania na serwerze.

Bardzo dobre spostrzeżenie wówczas po-któreś tam hashowanie nie ma znaczenia, tylko obciąża kod po stronie serwera. Jeśli tak mogę się wtrącić w dyskusję a do tego postu doszedłem tylko.
Natomiast hashowanie haseł nie jest metoda kompresji, ktoś kto tak myśli bardzo sie myli, to że powstają 32 znaki o tym nie świadczy, to błędny wniosek. Raz że takie hashowanie powinno być jednostronne a dwa że jest stratne, czyli za długie treści są obcinane, po to właśnie, aby nie można było odszyfrować tego hasła, nie zawsze tak jest, ale tak powinno być. Algorytm matematyczny nam to gwarantuje, unikalność hasha i tylko wyniki są porównywane jeśli tak to jestes zalogowany itp - to aluzja do wcześniejszego posta.
Natomiast co do łamiania algorytmów (nie brute force) to nie nie odbywa sie to tak jak sie wielu wydaje. Przykładem może być base64_encode, proszę sobie kilkukrotnie kodować jakąs treść i zobaczyć wynik. Jeśli dany algorytm jest złamany to nie będzie miało znaczenia ile razy był użyty bo będzie to rozpoznawalne, przedłuży pracę ale da sie zrobić i czas nie będzie zbytnio długi, bo złamanie nie jest tak czasochłonne jak brute force.
nospor
Skoro przytoczyles moja wypowiedz sprzed ponad 10 lat to ja moze tylko uaktualnei to troche:
wtedy byla mowa o zwyklym md5, sha1, i dodaniu jakiejs tam soli.
Teraz, gdy w metodach hashowania mozna okreslic, ze hashowanie ma zajac np. 1sekunde, to juz metoda hashowania na serwerze ma znaczenie, gdyz moze bardzo znacznie wydluzyc czas ataku BF i najzwyklej w swiecie taki atak sie nie powiedzie spowodow czasowych smile.gif
Przemek19
Nie lepiej zrobić coś takiego?
  1.  
  2. $haslo = "Konstantynopolitańczykówianeczka";
  3. $hash = hash(md5,$haslo);
  4.  
  5. for($i=1;$i<=10000;$i++)
  6. {
  7.  
  8. $hash = hash(sha1,$hash);
  9.  
  10. }
  11.  
  12. echo $hash;
  13.  
nospor
@Przemek19 Polecam przeczytac ten temat od poczatku. Masz tam wyjasnione czemu twoja metoda jest totalnie do bani i totalnie niebezpieczna
Przemek19
Ok, miałem 2 minuty, więc nie doczytałem tongue.gif
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.