Bcrypt vs Argon2: jaki hash haseł w 2026 roku

Bcrypt i Argon2 to dwie najczęściej używane dziś funkcje haszowania haseł. Obie zostały zaprojektowane jako wolne i odporne na ataki brute force, w przeciwieństwie do MD5 czy SHA-256, które z założenia są szybkie. Argon2 wygrał Password Hashing Competition w 2015 roku i jest obecnie wyborem rekomendowanym przez OWASP dla nowych aplikacji. Bcrypt pozostaje doskonałym, dojrzałym i szeroko wspieranym wyborem. Ten artykuł precyzyjnie wyjaśnia różnice, aby pomóc Ci zdecydować.

Dlaczego hash hasła jest inny

Klasyczny hash kryptograficzny, taki jak SHA-256, jest zaprojektowany, aby być szybki: chcemy haszować gigabajty danych na sekundę. Dla haseł ta właściwość jest wadą: atakujący, który pozyska Twoją tabelę użytkowników, może testować miliardy haseł na sekundę na GPU. Funkcja haszowania haseł (PHF, password hashing function) dąży natomiast do tego, aby być:

  • Wolna z założenia, z regulowanym parametrem kosztu
  • Z solą, aby uniemożliwić rainbow tables i równoległe ataki na wiele kont
  • Odporna na dedykowany sprzęt (GPU, FPGA, ASIC), aby ograniczyć przyspieszenie po stronie atakującego

Sól i parametr kosztu są przechowywane razem z hashem, w jednym ciągu typowo w postaci $algo$params$sol$hash. Pozwala to zwiększać koszt z czasem bez wymuszania natychmiastowej migracji starych hashy.

Bcrypt: 1999, Blowfish, parametr cost

Bcrypt został zaprojektowany przez Nielsa Provosa i Davida Mazièresa dla OpenBSD w 1999 roku. Opiera się na algorytmie szyfrującym Blowfish, którego wysoki koszt inicjalizacji tablic wykorzystuje. Bcrypt udostępnia jeden parametr, cost (lub rounds), który określa liczbę iteracji w postaci 2^cost. Zwiększenie cost o 1 podwaja czas obliczeń.

Typowy format wyjścia:

$2y$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
 |  |  |                      |
 |  |  cost = 12               sel + hash en base64
 |  variante (2y = openbsd)
 algo bcrypt

Bcrypt ogranicza wejście do 72 bajtów: dłuższe hasło jest cicho obcinane, co jest znaną pułapką. Typowym obejściem jest pre-haszowanie SHA-256, a następnie zakodowanie w base64 przed bcryptem, ale może to wprowadzić problematyczne null byte w niektórych implementacjach. Argon2 nie ma tego ograniczenia.

Argon2: 2015, zwycięzca PHC, 3 warianty

Argon2 został zaprojektowany przez Alexa Biryukova, Daniela Dinu i Dmitry'ego Khovratovicha. Wygrał Password Hashing Competition w lipcu 2015 roku i jest ustandaryzowany przez RFC 9106 (2021). Argon2 udostępnia trzy parametry:

  • Memory cost (m): ilość użytej pamięci, w KiB
  • Time cost (t): liczba iteracji na bloku pamięci
  • Parallelism (p): liczba równoległych wątków

Argon2 istnieje w trzech wariantach:

  • Argon2d: dostęp do pamięci zależny od danych. Bardziej odporny na ataki GPU, ale podatny na ataki kanałem bocznym (timing, cache).
  • Argon2i: dostęp do pamięci niezależny od danych. Odporny na side-channels, nieco mniej odporny na ataki GPU.
  • Argon2id: hybryda, startuje w trybie i, a następnie przełącza się w tryb d. Rekomendowany domyślnie przez RFC 9106 i OWASP.

Parametry rekomendowane przez OWASP w 2026 roku dla Argon2id: m=19456 KiB (19 MiB), t=2, p=1. Typowy format wyjścia:

$argon2id$v=19$m=19456,t=2,p=1$c2VsX2FsZWF0b2lyZQ$aGFzaF9jYWxjdWxl
 |         |   |                  |                 |
 |         |   parametres          sel base64        hash base64
 |         version
 algo argon2id

Dlaczego Argon2id jest rekomendowany

Odporność na dedykowany sprzęt jest dziś kryterium decydującym. Bcrypt używa niewiele pamięci (~4 KiB), co pozwala GPU z wyższej półki testować setki tysięcy hashy na sekundę. Argon2id jest memory-hard: wymuszenie kilku MiB pamięci na próbę drastycznie zmniejsza osiągalny paralelizm na GPU i sprawia, że projektowanie dedykowanych ASIC staje się ekonomicznie nieopłacalne.

Tryb hybrydowy Argon2id oferuje dodatkowo ochronę przed atakami kanałem bocznym podczas pierwszej połowy obliczeń. To właśnie ta kombinacja uzasadnia jego miejsce jako rekomendacji domyślnej OWASP, NIST SP 800-63B (od rewizji z 2024 roku) i RFC 9106.

Tabela porównawcza

Kryterium Bcrypt Argon2id
Rok19992015
StandaryzacjaDe facto, USENIX 1999RFC 9106 (2021)
Parametrycostmemory, time, parallelism
Używana pamięć~4 KiBKonfigurowalna (~19 MiB rekomendowane)
Memory-hardNieTak
Odporność na GPUUmiarkowanaSilna
Odporność na side-channelDobra (constant-time)Dobra (tryb id)
Limit wejścia72 bajtyBrak
Rekomendacja OWASP 2026AkceptowalnyPreferowany
Dojrzałość ekosystemuBardzo szerokaSzeroka od ~2018

Wydajność i odporność na ataki

Na nowoczesnym serwerze bcrypt z cost=12 zajmuje około 250 ms, a argon2id z parametrami OWASP około 100-300 ms zależnie od maszyny. Bezwzględny czas nie jest kryterium: liczy się stosunek między Twoim kosztem (jedno obliczenie, raz na login) a kosztem atakującego (miliardy obliczeń na GPU, aby złamać zrzut bazy).

Na RTX 4090 hashcat osiąga około 200 000 bcrypt/s przy cost=12, w porównaniu z kilkudziesięcioma tysiącami argon2id przy 19 MiB. Przy tym samym czasie obliczeń po stronie serwera Argon2id spowalnia atakującego 5 do 10 razy bardziej niż bcrypt, a różnica rośnie wraz z kolejnymi generacjami GPU.

Przykłady w PHP

PHP natywnie wspiera oba algorytmy poprzez password_hash() i password_verify() od PHP 7.2 dla Argon2i (i 7.3 dla Argon2id). Konstruktor PHP zarządza solą i formatem automatycznie.

Bcrypt

$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$ok   = password_verify($password, $hash);

if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
    $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}

Argon2id

$opts = [
    'memory_cost' => 19456,  // 19 MiB
    'time_cost'   => 2,
    'threads'     => 1,
];
$hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
$ok   = password_verify($password, $hash);

if (password_needs_rehash($hash, PASSWORD_ARGON2ID, $opts)) {
    $hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
}

Możesz generować lub identyfikować hashe wszystkich typów za pomocą naszego generatora hashy oraz naszego identyfikatora hashy.

Rekomendacja

Dla nowej aplikacji w 2026 roku wybierz Argon2id z parametrami OWASP jako bazą (m=19456, t=2, p=1), dostosowując do docelowego czasu (typowo 250 do 500 ms). Jeśli utrzymujesz istniejącą aplikację z bcryptem, nie ma pośpiechu w migracji: bcrypt z cost=12 lub wyższym pozostaje bezpieczny w 2026 roku. Skorzystaj z password_needs_rehash() przy następnym logowaniu, aby stopniowo migrować aktywnych użytkowników na Argon2id.

Bezwzględnie unikaj MD5, SHA-1 i samego SHA-256 do haseł (zobacz nasze porównanie MD5 vs SHA-256). Żaden z tych algorytmów nie jest zaprojektowany do tego zastosowania.

Często zadawane pytania

Czy bcrypt jest nadal bezpieczny w 2026 roku?

Tak, pod warunkiem użycia wystarczającego cost (minimum 12, najlepiej 14). Bcrypt nie ma znanej luki kryptograficznej. Jego jedyną względną słabością w stosunku do Argon2id jest niewielki ślad pamięciowy, który czyni go bardziej dostępnym dla ataków GPU i FPGA.

Czy trzeba migrować bazę bcrypt na Argon2id?

Nie pilnie. Stopniowa migracja z password_needs_rehash() jest rekomendowanym podejściem: przy każdym udanym logowaniu ponownie haszujesz hasło w Argon2id. Po kilku miesiącach większość aktywnych użytkowników jest zmigrowana, a Ty możesz wymusić reset hasła dla uśpionych kont.

Jaka jest właściwa liczba wątków dla Argon2id?

OWASP rekomenduje p=1 domyślnie. Zwiększanie p nic nie wnosi, jeśli Twój serwer webowy obsługuje już wiele żądań równolegle, i komplikuje strojenie. Lepiej zwiększać m (pamięć), które jest głównym czynnikiem odporności na GPU.

Czym jest „bcrypt decrypter”?

Nie istnieje deszyfrator bcrypt: funkcja jest jednokierunkowa z założenia. Narzędzia, które twierdzą, że „odszyfrowują” bcrypt, jedynie testują słowniki popularnych haseł względem hashu. To dokładnie to samo, co zrobiłby atakujący, który ma Twoją tabelę.

Argon2i czy Argon2id?

Argon2id w każdym przypadku dla haseł. Argon2i jest nieco bezpieczniejszy wobec side-channels, ale słabszy wobec ataków GPU. Argon2id łączy zalety obu i jest jawnie rekomendowany przez RFC 9106 do haszowania haseł.

Czy stosować pepper poza solą?

Sól wystarcza dla zdecydowanej większości aplikacji. Pepper (sekretny klucz przechowywany poza bazą danych i używany jako HMAC przed hashem) dodaje warstwę ochrony w przypadku wycieku bazy bez kompromitacji serwera aplikacyjnego. Argon2id nie dostarcza go natywnie, trzeba go złożyć ręcznie.