Przejdź do treści
Cappa

Argon2: jak z hasła powstaje klucz szyfrujący

Czym jest Argon2 i dlaczego utrudnia odgadywanie haseł? Wyjaśniamy rolę soli, pamięci i liczby przebiegów oraz porównujemy go z bcryptem i PBKDF2.

Kapibara obraca korbę prasy, która z kartki papieru wytwarza metalowy klucz.
W tym artykule

Argon2 utrudnia odgadywanie haseł, ponieważ każda próba wymaga czasu i pamięci. Służy zarówno do bezpiecznego przechowywania danych potrzebnych do logowania, jak i do wyprowadzania kluczy szyfrujących z hasła. Cappa korzysta z wariantu Argon2id: oblicza klucze w przeglądarce, zanim odblokuje notatki.

Wyjaśniamy, czym jest skrót kryptograficzny, dlaczego szybkie funkcje skrótu nie nadają się do ochrony haseł i do czego potrzebna jest sól. Następnie porównujemy Argon2 z bcryptem, scryptem i PBKDF2 oraz pokazujemy jego zastosowanie w Cappie.

Argon2: co to jest?

Argon2 jest funkcją przeznaczoną do przetwarzania haseł. Otrzymuje hasło, sól i parametry kosztu, a zwraca ciąg bajtów o ustalonej długości. Dla tych samych danych daje ten sam wynik. Nie ma praktycznego sposobu, by odwrócić to obliczenie, ale można sprawdzać kolejnych kandydatów na hasło.

Argon2 powstał w ramach Password Hashing Competition, otwartego konkursu, w którym kryptografowie od 2013 do 2015 roku szukali lepszego sposobu ochrony haseł. W lipcu 2015 roku jury ogłosiło go zwycięzcą. We wrześniu 2021 roku IETF opublikowała go jako RFC 9106, formalną specyfikację, według której powstają implementacje.

Funkcja wyprowadzania klucza (KDF)
Funkcja, która z jednego sekretu (tu: Twojego hasła) tworzy klucze kryptograficzne o stałym rozmiarze. KDF oparta na haśle jest celowo powolna, żeby zgadywanie haseł było kosztowne.

Czym jest skrót: odcisk palca danych

Funkcja skrótu przyjmuje dowolne dane, jedno słowo albo cały film, i tworzy krótki „odcisk palca” o stałej długości. SHA-256, jedna z najpopularniejszych, zawsze daje 256 bitów, zwykle zapisywanych jako 64 znaki szesnastkowe.

Dobra funkcja skrótu jest deterministyczna: te same dane dają ten sam wynik. Niewielka zmiana wejścia znacząco zmienia wynik, a znalezienie danych pasujących do zadanego skrótu powinno być obliczeniowo trudne. Tak wyglądają skróty SHA-256 dwóch słów, które różnią się tylko wielkością pierwszej litery:

SHA-256("notatka") = 2dd802ecd137b014aab569707cb21036d45e7365bbad2f756b97c1009183df41
SHA-256("Notatka") = a2db53fb98a78ef528bc8ed63955d6f41d04c55854ded41fb549030a75fad843

Przy poprawnym przechowywaniu haseł serwis zapisuje wynik funkcji przeznaczonej do haseł, wraz z solą i parametrami. Podczas logowania powtarza obliczenie i sprawdza wynik. Wyciek bazy ujawnia wtedy dane pozwalające zgadywać hasła offline, ale nie same hasła wprost.

Haszowanie haseł: dlaczego szybkie skróty to złe narzędzie

Napastnik nie musi odwracać funkcji skrótu. Może zgadywać hasło, obliczać wynik dla każdego kandydata i porównywać go ze skradzionym wynikiem. Przy słabym haśle takie sprawdzanie może szybko zakończyć się sukcesem.

SHA-256 i MD5 są szybkimi funkcjami skrótu. W wielu zastosowaniach to zaleta, ale przy hasłach działa na korzyść napastnika. W publicznych testach hashcata karta RTX 4090 oblicza około 163 miliardów skrótów MD5 i 22 miliardów SHA-256 na sekundę. Jeśli hasło ma przewidywalną postać, pozwala to sprawdzić ogromną liczbę kandydatów w krótkim czasie.

Funkcje przeznaczone do haseł celowo ograniczają tę szybkość. Pojedyncze logowanie powinno nadal trwać krótko, ale sprawdzenie milionów kandydatów musi wymagać znacznie więcej pracy.

Sól: składnik inny dla każdego konta

Bez soli można by raz obliczyć skróty popularnych haseł i używać tej samej tabeli przy atakach na wiele kont. Identyczne hasła dawałyby też identyczne wyniki, ujawniając, którzy użytkownicy wybrali to samo hasło.

Sól
Wartość dodawana do hasła przed haszowaniem, inna dla każdego konta. Nie musi być tajna. Jej zadaniem jest sprawić, że to samo hasło daje różne wyniki u różnych osób, więc każde konto trzeba atakować osobno.

Sól jest jawna i zwykle zapisuje się ją obok wyniku. Nie utrudnia odgadnięcia samego hasła. Nie pozwala natomiast użyć jednego gotowego zestawu wyników do ataku na wszystkie konta naraz.

Cappa wyprowadza sól z adresu e-mail, losowego 16-bajtowego ziarna, stałej etykiety i numeru wersji za pomocą SHA-256. Nowe ziarno powstaje przy rejestracji, zmianie hasła i odzyskaniu konta. Kod aplikacji ustala parametry Argon2id i uwzględnia adres konta w soli, co utrudnia serwerowi narzucenie wspólnej soli wielu kontom lub obniżenie kosztu obliczeń. Ta ochrona zakłada, że przeglądarka uruchamia niezmodyfikowany kod aplikacji.

Dlaczego Argon2 potrzebuje dużo pamięci

Koszt obliczeń można zwiększyć przez wielokrotne powtarzanie operacji, jak w PBKDF2. Procesory graficzne i wyspecjalizowane układy potrafią jednak wykonywać wiele takich obliczeń równolegle.

Argon2 wymaga również pamięci. Wypełnia ją danymi i wielokrotnie odczytuje wcześniej obliczone bloki. Kto próbuje oszczędzić pamięć, musi wykonać dodatkową pracę, co ogranicza korzyści z równoległego sprawdzania wielu haseł.

Tę właściwość nazywa się po angielsku memory-hardness (po polsku: pamięciochłonność): istotną część kosztu stanowi użycie pamięci. Informacje o wydaniu hashcata 7.0 podają około 1703 prób na sekundę na RTX 4090 przy parametrach odpowiadających Cappie. W cytowanym wyżej teście ta sama karta liczy około 163 miliardów skrótów MD5 na sekundę. Co oznacza ta różnica, pokazujemy w artykule o długości hasła głównego.

Argon2d, Argon2i i Argon2id: który wariant?

RFC 9106 opisuje trzy warianty. Argon2d wybiera, którą część pamięci odczytać, na podstawie samych danych. Dobrze opiera się atakom z użyciem kart graficznych, ale na współdzielonym komputerze może zdradzać informacje przez czas wykonywania operacji. Argon2i czyta pamięć w stałej kolejności, niezależnej od hasła, co zamyka ten wyciek. Argon2id przez pierwszą połowę pierwszego przebiegu działa jak Argon2i, a potem jak Argon2d, łącząc zalety obu.

RFC wymaga, żeby każda implementacja obsługiwała Argon2id, i radzi wybrać go w razie wątpliwości. Zestawienie zaleceń OWASP Password Storage Cheat Sheet, przygotowane przez organizację OWASP zajmującą się bezpieczeństwem aplikacji, również stawia go na pierwszym miejscu. Cappa używa Argon2id.

Parametry Argon2id w Cappie

UstawienieCo oznaczaWartość w Cappie
Pamięć (m)Ilość pamięci przeznaczonej na jedno obliczenie64 MiB
Przebiegi (t)Ile razy obliczenie przechodzi przez tę pamięć3
Równoległość (p)Ile niezależnych torów (wątków obliczeń) może działać jednocześnie1
Długość wynikuRozmiar wyprowadzonego klucza32 bajty (256 bitów)

Dla porównania: druga zalecana opcja w RFC 9106 to 64 MiB, 3 przebiegi i 4 tory. Cappa używa tej samej pamięci i liczby przebiegów z jednym torem, co pasuje do pojedynczego wątku w tle przeglądarki. Minimum OWASP dla haseł przechowywanych na serwerze jest niższe (na przykład 19 MiB i 2 przebiegi), bo obciążony serwer haszuje hasła wielu użytkowników naraz.

Ile trwa jedno obliczenie? W naszym teście na laptopie z procesorem Apple M4 Pro jedno uruchomienie z ustawieniami Cappy, przy użyciu tej samej biblioteki WebAssembly co aplikacja, trwało około 0,1 sekundy. Starsze telefony potrzebują zauważalnie więcej. Ty płacisz ten koszt raz, przy odblokowaniu. Napastnik płaci go przy każdej próbie.

Hasło do logowania a klucz szyfrujący: dwie różne role

Ten sam Argon2 może wykonywać dwa różne zadania, a różnica ma znaczenie.

Haszowanie hasła logowania (serwer)

  • Serwer przechowuje skrót i porównuje go przy każdym logowaniu
  • Serwer może ograniczać próby, blokować konta i ostrzegać
  • Koszt haszowania można zwiększyć przy kolejnym poprawnym logowaniu
  • Wykradziony skrót pozwala zgadywać offline

Wyprowadzanie klucza szyfrującego (Twoje urządzenie)

  • Wynik służy do ochrony klucza do danych i powinien pozostać na urządzeniu
  • Każdy, kto ma kopię zaszyfrowanych danych, może zgadywać offline i nikt go nie zatrzyma
  • Ustawienia są częścią formatu danych, więc ich zmiana wymaga nowej wersji
  • Parametry muszą uwzględniać wydajność obsługiwanych urządzeń, również telefonów

W aplikacji z szyfrowaniem end-to-end (E2EE) klucz wyprowadza się na urządzeniu, bo serwer nie powinien otrzymywać hasła głównego. Koszt tej operacji utrudnia atak offline na skradzione dane, ale o liczbie potrzebnych prób decyduje również nieprzewidywalność hasła.

Funkcja wyprowadzania klucza w praktyce: jak Cappa zamienia hasło w klucze

Cappa wykonuje oba zadania, w tej kolejności:

Hasło główne + sól

Twoje hasło oraz sól z adresu e-mail i losowego, 16-bajtowego ziarna

w Web Workerze

Argon2id

64 MiB, 3 przebiegi, 1 tor

Klucz główny

32 bajty, z których HKDF-SHA-256 wyprowadza dwa niezależne klucze

Klucz logowania

Potwierdza Twoją tożsamość przy logowaniu

HTTPS

Serwer

Ponownie haszuje klucz logowania funkcją Argon2id i przechowuje tylko ten skrót

Klucz hasła (KEK)

Nigdy nie opuszcza przeglądarki

otwiera

Koperta hasła

Zawiera losowy klucz, który szyfruje Twoje notatki

Wyprowadzanie kluczy w Cappie. Hasło i klucz szyfrujący pozostają w przeglądarce; serwer otrzymuje osobny klucz służący do logowania.
  1. Hasło zostaje przygotowane. Aplikacja zamienia je na standardową postać Unicode (NFC) i koduje jako bajty. Nic nie jest przycinane, więc spacje się liczą.

  2. Argon2id działa w Web Workerze. Obliczenia wykonują się w osobnym wątku, dzięki czemu nie blokują obsługi strony. Ich wynikiem jest 32-bajtowy klucz główny (root key).

  3. HKDF wyprowadza dwa osobne klucze. HKDF-SHA-256 (RFC 5869) tworzy z jednego silnego sekretu klucze do różnych zastosowań. Każdy powstaje z inną etykietą, więc ich role są rozdzielone: klucz logowania (authKey) służy do logowania, a klucz hasła (KEK, key-encryption key) do odszyfrowania innego klucza.

  4. Klucz logowania potwierdza, kim jesteś. Trafia na serwer i pełni tam rolę hasła do konta. Przed zapisaniem serwer ponownie haszuje go funkcją Argon2id, więc kopia bazy nie zawiera wartości, która od razu pozwala się zalogować.

  5. Klucz hasła otwiera sejf. Sejf to zaszyfrowany zbiór Twoich notatek. Klucz hasła nigdy nie opuszcza przeglądarki. Odszyfrowuje małą kopertę hasła z kluczem sejfu, czyli losowym, 256-bitowym kluczem, który szyfruje Twoje notatki algorytmem AES-256-GCM.

Znajomość klucza logowania nie zdradza klucza hasła, bo HKDF wyprowadza oba klucze niezależnie. Samo hasło nigdy nie opuszcza przeglądarki. Pełną listę tego, co przechowuje serwer, znajdziesz w tekście o tym, co widzi serwer.

Argon2 na tle bcrypta, scrypta i PBKDF2

Wszystkie cztery funkcje służą do przetwarzania haseł, ale różnią się zużyciem zasobów i ograniczeniami.

FunkcjaRokCo jest kosztowneUstawienia OWASP (stan na wrzesień 2026)Ocena
Argon2id2015 (RFC 9106 w 2021)Czas i regulowana ilość pamięciMinimum 19 MiB, 2 przebiegi, 1 tor (lub odpowiednik)Pierwszy wybór w nowych systemach
scrypt2009Czas i pamięćN=2¹⁷ (128 MiB), r=8, p=1Mocny; wybór OWASP, gdy Argon2id jest niedostępny
bcrypt1999Czas, przy małej, stałej pamięci (ok. 4 KiB)Współczynnik kosztu co najmniej 10; hasła do 72 bajtówWciąż do przyjęcia w starszych systemach; limit 72 bajtów i mała pamięć zdradzają wiek
PBKDF22000Tylko czas (powtarzane haszowanie)600 000 iteracji z HMAC-SHA-256Gdy wymagana jest zgodność z FIPS-140; najtańszy do atakowania kartami graficznymi

Wartości OWASP pochodzą z Password Storage Cheat Sheet, który podaje też równoważne zestawy ustawień dla Argon2id i scrypta: mniej pamięci w zamian za więcej przebiegów. Te minima dotyczą serwerów obsługujących wiele logowań. Przy kluczu liczonym raz na Twoim urządzeniu można sobie pozwolić na więcej, dlatego Cappa używa 64 MiB i 3 przebiegów.

W nowych systemach warto wybrać Argon2id zgodnie z zaleceniem OWASP. Bcrypt nadal ma zastosowanie w istniejących systemach, lecz ogranicza długość hasła do 72 bajtów i nie oferuje regulowanego kosztu pamięci.

Czego powolne haszowanie nie zrobi

Najczęstsze pytania

Czy Argon2 to szyfrowanie?

Nie. Szyfrowanie da się odwrócić właściwym kluczem, a Argon2 to funkcja jednokierunkowa. W Cappie Argon2id tworzy klucze, a samym szyfrowaniem zajmuje się osobny szyfr, AES-256-GCM.

Czy Argon2 jest lepszy od bcrypta?

OWASP zaleca Argon2id w nowych systemach, a bcrypt pozostawia jako rozwiązanie dla starszych wdrożeń. Argon2id pozwala dobrać koszt pamięci i nie ma charakterystycznego dla bcrypta limitu 72 bajtów. Bezpieczeństwo obu zależy jednak od konfiguracji i jakości hasła.

Czy skrót Argon2 da się złamać?

Nie znamy praktycznej metody odwrócenia tej funkcji. Można jednak obliczać skróty kolejnych kandydatów i porównywać wyniki. Argon2id zwiększa koszt każdej próby, ale nie ochroni popularnego hasła, które napastnik sprawdzi na samym początku.

Dlaczego odblokowanie Cappy trwa chwilę?

Przy wyprowadzaniu kluczy urządzenie wykonuje Argon2id z 64 MiB pamięci i 3 przebiegami. Opóźnienie jest zamierzone: osoba zgadująca hasło musi ponieść koszt tego obliczenia przy każdej próbie.

Czy serwer kiedykolwiek widzi moje hasło główne?

Nie. Serwer dostaje tylko wyprowadzony z niego klucz logowania i ponownie haszuje go funkcją Argon2id. Warunek: kod aplikacji uruchomiony w Twojej przeglądarce musi być oryginalny. Kod podmieniony na przejętym serwerze mógłby przechwycić hasło.

Powiadomimy Cię o otwarciu Cappy

Na razie Cappa jest dostępna tylko na zaproszenie. Planowana cena to 29 € rocznie. Zostaw e-mail, a powiadomimy Cię, gdy otworzymy dostęp. Zapis jest bezpłatny i nie zobowiązuje do zakupu.

Adresu użyjemy tylko po to, by powiadomić Cię o otwarciu dostępu. Link w e-mailu pozwala go w każdej chwili usunąć.

Autor: zespół Cappy

Tworzymy aplikację Cappa do notatek w Markdownie. Szyfruje ona treść na Twoim urządzeniu przed wysłaniem jej na serwer. Wyjaśniamy, jak działa ta ochrona i jakie ma ograniczenia.