Co jakiś czas słyszę radę „Używaj bcrypt do przechowywania haseł w PHP, reguły bcrypt”.
Ale co to jest bcrypt
? PHP nie oferuje takich funkcji, Wikipedia bełkocze o narzędziu do szyfrowania plików, a wyszukiwania w Internecie ujawniają tylko kilka implementacji Blowfish w różnych językach. Teraz Blowfish jest również dostępny w PHP za pośrednictwem mcrypt
, ale jak to pomaga w przechowywaniu haseł? Blowfish to szyfr ogólnego przeznaczenia, działa na dwa sposoby. Jeśli można go zaszyfrować, można go odszyfrować. Hasła wymagają jednokierunkowej funkcji skrótu.
Jakie jest wyjaśnienie?
bcrypt
jest jednokierunkowa mieszania algorytm kontra programu szyfrującego w mojej odpowiedzi . Istnieje całe nieporozumienie, którebcrypt
jest po prostu Blowfish, gdy w rzeczywistości ma on zupełnie inny kluczowy harmonogram, który zapewnia, że zwykły tekst nie może zostać odzyskany z tekstu zaszyfrowanego bez znajomości początkowego stanu szyfru (sól, zaokrąglenia, klucz).Odpowiedzi:
bcrypt
jest algorytmem mieszającym, który jest skalowalny sprzętowo (poprzez konfigurowalną liczbę rund). Jego powolność i wielokrotność rund sprawiają, że atakujący musi przeznaczyć ogromne środki i sprzęt, aby móc złamać hasło. Dodaj do tego sole na hasło (bcrypt
WYMAGA soli) i możesz być pewien, że atak jest praktycznie niewykonalny bez absurdalnej ilości funduszy lub sprzętu.bcrypt
używa algorytmu Eksblowfish do mieszania haseł. Podczas gdy faza szyfrowania Eksblowfish i Blowfish są dokładnie takie same, faza harmonogramu klucza Eksblowfish zapewnia, że każdy kolejny stan zależy zarówno od soli, jak i klucza (hasło użytkownika) i żaden stan nie może zostać obliczony bez znajomości obu. Z powodu tej kluczowej różnicybcrypt
jest algorytmem mieszającym jednokierunkowym. Nie możesz odzyskać hasła w postaci zwykłego tekstu bez znajomości soli, rund i klucza (hasła). [ Źródło ]Jak korzystać z bcrypt:
Korzystanie z PHP> = 5,5-DEV
Funkcje haszujące hasła zostały teraz wbudowane bezpośrednio w PHP> = 5.5 . Możesz teraz użyć
password_hash()
do utworzeniabcrypt
skrótu dowolnego hasła:Aby zweryfikować hasło podane przez użytkownika w stosunku do istniejącego skrótu, możesz użyć
password_verify()
jako takiego:Przy użyciu PHP> = 5.3.7, <5.5-DEV (także RedHat PHP> = 5.3.3)
Jest biblioteka kompatybilność na GitHub utworzone na podstawie kodu źródłowego powyższych funkcji w C pierwotnie napisane, który zapewnia taką samą funkcjonalność. Po zainstalowaniu biblioteki kompatybilności użycie jest takie samo jak powyżej (minus notacja skrócona, jeśli nadal jesteś w gałęzi 5.3.x).
Korzystanie z PHP <5.3.7 (DEPRECATED)
Możesz użyć
crypt()
funkcji do generowania skrótów bcrypt ciągów wejściowych. Ta klasa może automatycznie generować sole i weryfikować istniejące skróty na podstawie danych wejściowych. Jeśli używasz wersji PHP wyższej lub równej 5.3.7, zaleca się użycie wbudowanej funkcji lub biblioteki kompatybilności . Ta alternatywa jest przewidziana wyłącznie do celów historycznych.Możesz użyć tego kodu w następujący sposób:
Alternatywnie możesz także użyć Portable PHP Hashing Framework .
źródło
mt_rand()
jest on również obsadzony przy użyciu bieżącej godziny i bieżącego identyfikatora procesu. Proszę zobaczyćGENERATE_SEED()
w/ext/standard/php_rand.h
.crypt()
jest wtedy przejrzeć i zweryfikować. Powyższy kod wywołuje PHPcrypt()
, który wywołuje funkcję POSIXcrypt()
. Cały powyższy kod nie tylko generuje losową sól (która nie musi być zabezpieczona kryptograficznie, sól nie jest uważana za tajemnicę) przed wywołaniemcrypt()
. Może powinieneś zrobić trochę badań przed wezwaniem wilka.crypt()
) podlega luce w zabezpieczeniach wcześniejszej niż 5.3.7 i jest (bardzo nieznacznie) nieefektywny po 5.3.7 - szczegółowe informacje na ten temat można znaleźć tutaj . Należy również pamiętać, że nowy interfejs API haszowania haseł ( wsteczna kompatybilność lib ) jest teraz preferowaną metodą implementacji haszowania haseł bcrypt w Twojej aplikacji.Więc chcesz użyć bcrypt? Niesamowite! Jednak, podobnie jak inne obszary kryptografii, nie powinieneś robić tego sam. Jeśli musisz się martwić o zarządzanie kluczami, przechowywanie soli lub generowanie liczb losowych, robisz to źle.
Powód jest prosty: tak banalnie łatwo jest zepsuć bcrypt . W rzeczywistości, jeśli spojrzysz na prawie każdy fragment kodu na tej stronie, zauważysz, że narusza on co najmniej jeden z tych typowych problemów.
Twarzą w twarz, kryptografia jest trudna.
Pozostaw to ekspertom. Pozostaw to osobom, których zadaniem jest utrzymanie tych bibliotek. Jeśli musisz podjąć decyzję, robisz to źle.
Zamiast tego po prostu użyj biblioteki. Istnieje kilka w zależności od wymagań.
Biblioteki
Oto podział niektórych z bardziej popularnych interfejsów API.
PHP 5.5 API - (dostępny dla 5.3.7+)
Począwszy od PHP 5.5, wprowadzany jest nowy interfejs API do mieszania haseł. Istnieje również biblioteka kompatybilności shim utrzymywana (przeze mnie) dla wersji 5.3.7+. Ma to tę zaletę, że jest recenzowaną i prostą w użyciu implementacją.
Naprawdę ma to być bardzo proste.
Zasoby:
Zend \ Crypt \ Password \ Bcrypt (5.3.2+)
Jest to kolejny interfejs API podobny do PHP 5.5, który ma podobny cel.
Zasoby:
PasswordLib
Jest to nieco inne podejście do mieszania haseł. Zamiast obsługiwać bcrypt, PasswordLib obsługuje wiele algorytmów mieszających. Jest to szczególnie przydatne w kontekstach, w których należy wspierać zgodność ze starszymi i różnorodnymi systemami, które mogą być poza twoją kontrolą. Obsługuje dużą liczbę algorytmów mieszających. I jest obsługiwany 5.3.2+
Bibliografia:
PHPASS
Jest to warstwa, która obsługuje bcrypt, ale obsługuje również dość silny algorytm, który jest użyteczny, jeśli nie masz dostępu do PHP> = 5.3.2 ... W rzeczywistości obsługuje PHP 3.0+ (choć nie z bcrypt).
Zasoby
Uwaga: Nie używaj alternatyw PHPASS, które nie są hostowane na openwall, są to różne projekty !!!
O BCrypt
Jeśli zauważysz, każda z tych bibliotek zwraca pojedynczy ciąg. To dlatego, że BCrypt działa wewnętrznie. I jest mnóstwo odpowiedzi na ten temat. Oto wybór, który napisałem, którego nie skopiuję / wkleję tutaj, ale link do:
md5
haseł do bcryptZakończyć
Istnieje wiele różnych opcji. To, co wybierzesz, zależy od ciebie. Chciałbym jednak WYSOCE zalecane jest użycie jednego z powyższych bibliotek do obsługi to za Ciebie.
Ponownie, jeśli używasz
crypt()
bezpośrednio, prawdopodobnie robisz coś złego. Jeśli Twój kod używa bezpośredniohash()
(lubmd5()
lubsha1()
), prawie na pewno robisz coś złego.Po prostu skorzystaj z biblioteki ...
źródło
mt_rand()
Ma więc wystarczająco długi okres, ale wartość początkowa wynosi tylko 32 bity. Zatem używaniemt_rand()
skutecznie ogranicza cię tylko do 32 bitów entropii. Który dzięki Problemowi Urodzinowemu oznacza, że masz 50% szansy na kolizję tylko przy 7k generowanych solach (globalnie). Ponieważbcrypt
akceptuje 128 bitów soli, lepiej jest użyć źródła, które może dostarczyć wszystkie 128 bitów ;-). (przy 128 bitach 50% szansy na kolizję dzieje się przy haszach 2e19) ...mt_rand
iuniqid
(a więclcg_value
irand
) nie są pierwszymi wyborami ...Zdobędziesz wiele informacji w „ Wystarczy z tablicami Rainbow”: Co musisz wiedzieć o bezpiecznych schematach haseł lub przenośnym frameworku hasłowym PHP .
Celem jest haszowanie hasła czymś powolnym, więc ktoś, kto dostanie bazę danych haseł, zginie, próbując go brutalnie wymusić (opóźnienie 10 ms, aby sprawdzić hasło, nie jest dla ciebie niczym, dużo dla kogoś, kto próbuje go brutalnie wymusić). Bcrypt jest wolny i można go używać z parametrem, aby wybrać jego szybkość .
źródło
Możesz utworzyć jednokierunkowy skrót za pomocą bcrypt, używając
crypt()
funkcji PHP i przekazując odpowiednią sól Blowfish. Najważniejsze z całego równania jest to, że A) algorytm nie został naruszony, a B) poprawnie słone każde hasło . Nie używaj soli do aplikacji; który otwiera całą twoją aplikację do ataku z jednego zestawu tabel Rainbow.PHP - funkcja szyfrowania
źródło
crypt()
funkcji PHP , która obsługuje kilka różnych funkcji mieszania hasła. Upewnij się, że nie używaszCRYPT_STD_DES
lubCRYPT_EXT_DES
- żaden inny obsługiwany typ jest w porządku (i zawiera bcrypt, pod nazwąCRYPT_BLOWFISH
).crypt
udostępnia kilka skrótów haseł, przy czym bcrypt odpowiadaCRYPT_BLOWFISH
stałej. Bcrypt jest obecnie najsilniejszym obsługiwanym algorytmem,crypt
a kilka innych obsługiwanych przez niego algorytmów jest dość słabych.Edycja: 2013.01.15 - Jeśli twój serwer będzie go obsługiwał, użyj zamiast tego rozwiązania martinstoeckli .
Każdy chce, aby było to bardziej skomplikowane niż jest. Funkcja crypt () wykonuje większość pracy.
Przykład:
Wiem, że powinno to być oczywiste, ale nie używaj hasła jako hasła.
źródło
2y
zamiast2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
jako źródła soli.bcrypt
zastosowania alfabetu .mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
Wersja 5.5 PHP będzie miała wbudowane wsparcie dla BCrypt, funkcji
password_hash()
ipassword_verify()
. W rzeczywistości są to tylko opakowania wokół funkcjicrypt()
i powinny ułatwić jej prawidłowe użycie. Dba o generowanie bezpiecznej losowej soli i zapewnia dobre wartości domyślne.Najłatwiejszym sposobem korzystania z tych funkcji będzie:
Ten kod będzie mieszał hasło z BCrypt (algorytm
2y
), generuje losową sól z losowego źródła systemu operacyjnego i używa domyślnego parametru kosztu (w tej chwili jest to 10). Drugi wiersz sprawdza, czy użytkownik wpisał hasło odpowiada już zapisanej wartości skrótu.Jeśli chcesz zmienić parametr kosztu, możesz to zrobić w ten sposób, zwiększając parametr kosztu o 1, podwajając czas potrzebny do obliczenia wartości skrótu:
W przeciwieństwie do
"cost"
parametru najlepiej jest go pominąć"salt"
, ponieważ funkcja już robi wszystko, aby utworzyć sól kryptograficznie bezpieczną.Dla PHP w wersji 5.3.7 i nowszych istnieje pakiet kompatybilności od tego samego autora, który utworzył tę
password_hash()
funkcję. Dla wersji PHP 5.3.7 przed nie ma wsparciacrypt()
ze2y
, Unicode algorytm bezpiecznego BCrypt. Zamiast tego można go zastąpić2a
, co jest najlepszą alternatywą dla wcześniejszych wersji PHP.źródło
Obecne myślenie: skróty powinny być najwolniej dostępne, a nie najszybsze z możliwych. To hamuje tęczowe tablice ataków.
Również powiązane, ale ostrożne: osoba atakująca nigdy nie powinna mieć nieograniczonego dostępu do ekranu logowania. Aby temu zapobiec: skonfiguruj tabelę śledzenia adresów IP, która rejestruje każde trafienie wraz z identyfikatorem URI. Jeśli więcej niż 5 prób zalogowania pochodzi z tego samego adresu IP w dowolnym okresie pięciu minut, zablokuj z wyjaśnieniem. Drugim podejściem jest posiadanie dwupoziomowego systemu haseł, podobnie jak banki. Blokowanie błędów podczas drugiego przejścia zwiększa bezpieczeństwo.
Podsumowanie: spowolnij atakującego za pomocą czasochłonnych funkcji skrótu. Zablokuj też zbyt wiele dostępów do loginu i dodaj drugą warstwę haseł.
źródło
Oto zaktualizowana odpowiedź na to stare pytanie!
Właściwy sposób mieszania haseł w PHP od wersji 5.5
password_hash()
, a właściwy sposób na ich weryfikację -password_verify()
i tak jest nadal w PHP 8.0. Te funkcje domyślnie używają skrótów bcrypt, ale dodano inne silniejsze algorytmy. Możesz zmienić współczynnik pracy (efektywnie „silny” szyfrowanie) za pomocąpassword_hash
parametrów.Jednak pomimo tego, że wciąż jest wystarczająco silny, bcrypt nie jest już uważany za najnowocześniejszy ; przybył lepszy zestaw algorytmów mieszających hasła o nazwie Argon2 , z wariantami Argon2i, Argon2d i Argon2id. Różnica między nimi (jak opisano tutaj ):
Obsługa języka Argon2i została dodana w PHP 7.2 i żądasz tego w następujący sposób:
i wsparcie dla Argon2id zostało dodane w PHP 7.3:
Weryfikacja haseł nie wymaga żadnych zmian, ponieważ wynikowy ciąg hash zawiera informacje o tym, jaki algorytm, sól i czynniki robocze zostały użyte podczas jego tworzenia.
Zupełnie osobno (i nieco redundantnie) libsodium (dodane w PHP 7.2) zapewnia również haszowanie Argon2 poprzez funkcje
sodium_crypto_pwhash_str ()
isodium_crypto_pwhash_str_verify()
, które działają podobnie jak wbudowane PHP. Jednym z możliwych powodów ich zastosowania jest to, że PHP może być czasem kompilowane bez libargon2, co powoduje, że algorytmy Argon2 są niedostępne dla funkcji hashash; PHP 7.2 i nowsze wersje zawsze powinny mieć włączoną bibliotekę libsodium, ale może nie - ale przynajmniej istnieją dwa sposoby uzyskania tego algorytmu. Oto, w jaki sposób możesz utworzyć skrót Argon2id za pomocą libsodium (nawet w PHP 7.2, który inaczej nie obsługuje Argon2id):Zauważ, że nie pozwala ci to ręcznie określić soli; jest to część etosu libsodium - nie pozwól użytkownikom ustawiać parametrów na wartości, które mogłyby zagrozić bezpieczeństwu - na przykład nic nie stoi na przeszkodzie, abyś przekazał pusty ciąg soli do
password_hash
funkcji PHP ; libsodium nie pozwala ci robić nic tak głupiego!źródło
W przypadku haseł OAuth 2 :
źródło
Jak wszyscy wiemy, przechowywanie hasła w postaci zwykłego tekstu w bazie danych nie jest bezpieczne. bcrypt to technika mieszania haseł. Służy do budowania bezpieczeństwa haseł. Jedną z niesamowitych funkcji bcrypt jest to, że ratuje nas przed hakerami, służy do ochrony hasła przed atakami hakerów, ponieważ hasło jest przechowywane w formie bcrypted.
funkcja password_hash () służy do tworzenia nowego skrótu hasła. Wykorzystuje silny i solidny algorytm mieszający. Funkcja password_hash () jest bardzo kompatybilna z funkcją crypt (). Dlatego skróty haseł utworzone przez crypt () mogą być używane z password_hash () i odwrotnie. Funkcje password_verify () i password_hash () po prostu otaczają funkcję crypt () i znacznie ułatwiają jej dokładne użycie.
SKŁADNIA
Następujące algorytmy są obecnie obsługiwane przez funkcję password_hash ():
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parametry: Ta funkcja przyjmuje trzy parametry, jak wspomniano powyżej i opisano poniżej:
hasło : Przechowuje hasło użytkownika. algo : Jest to stała algorytmu hasła, która jest używana w sposób ciągły podczas oznaczania algorytmu, który ma być używany, gdy następuje haszowanie hasła. opcje : Jest to tablica asocjacyjna, która zawiera opcje. Jeśli zostanie to usunięte i nie zostanie uwzględnione, zostanie użyta losowa sól i nastąpi wykorzystanie domyślnego kosztu. Zwracana wartość : Zwraca hashowane hasło w przypadku sukcesu lub False w przypadku niepowodzenia.
Przykład :
Poniższe programy ilustrują funkcję password_hash () w PHP:
WYNIK
źródło