Pierwszy wiersz zapisuje dokładne użyte parametry (algorytm, odczyt, rozmiary wejść), więc skopiowany wynik zawsze da się odtworzyć.
HMAC, PBKDF2 i HKDF — haszowanie z kluczem wyjaśnione od podstaw
W jednym zdaniu: goły skrót, jak SHA-256, może obliczyć każdy, więc nie dowodzi, kto wysłał wiadomość — HMAC miesza tajny klucz, więc tylko posiadacze klucza mogą wytworzyć (lub zweryfikować) skrót; PBKDF2 i HKDF potem wykorzystują tę samą maszynerię HMAC, by zamieniać sekrety w klucze — wolno dla haseł, szybko dla materiału już losowego.
Czym jest HMAC (RFC 2104)
Konstrukcja. HMAC to dwa przebiegi skrótu, a nie jeden. Klucz jest dopełniany do rozmiaru bloku skrótu (64 bajty dla MD5/SHA-1/SHA-256, 128 dla SHA-384/512); wiadomość jest haszowana raz z kluczem XOR stałą wewnętrzną wyściółką, a ten skrót jest haszowany ponownie z kluczem XOR stałą zewnętrzną wyściółką. Ta podwójna kanapka jest dowodliwie bezpieczna, o ile bazowy skrót jest przyzwoitą funkcją pseudolosową — dlatego HMAC-MD5 wciąż opiera się praktycznym atakom na kolizje, które złamały zwykły MD5 (choć i tak jest wycofany, zobacz niżej).
Klucze. Działa każda długość klucza: krótszy niż rozmiar bloku jest używany tak jak jest (ale poniżej 32 bajtów patrzy się krzywo), dłuższy najpierw jest haszowany. Ta sama strona pozwala wpisać klucz jako tekst, hex lub Base64, tak aby 64-znakowy produkcyjny klucz hex mógł być wklejony bez pomylenia go z 64-znakowym hasłem tekstowym — sposób odczytu jest zapisany w wierszu wyjścia właśnie z tego powodu.
Gdzie to występuje. Pole HS256 w nagłówku JWT to dosłownie HMAC-SHA-256 nad zakodowanymi w base64url częściami tokenu (Dekoder JWT na tej stronie oblicza dokładnie to, po wklejeniu sekretu HS256). Podpisy webhooków (Stripe, GitHub), AWS SigV4, ochrona rekordów TLS (starsze wersje) i kuzyn OpenSSH umac-64@openssh.com należą do tej samej rodziny.
Dlaczego nie po prostu hash(wiadomość || klucz)? Rozszerzenie długości: każdy skrót z rodziny MD5/SHA-1/SHA-2 pozwala atakującemu, który zna H(sekret || msg), obliczyć H(sekret || msg || dopełnienie || cokolwiek) bez sekretu. Podział HMAC na wewnętrzny i zewnętrzny kończy z tą klasą ataków. To najczęstszy błąd typu zrób-sam w kodzie podpisów API — i powód, dla którego HMAC istnieje.
Czym jest PBKDF2 (RFC 8018)
Wolny z założenia. Hasło ma może 40 bitów realnej entropii; GPU atakującego próbuje miliardy surowych SHA-256 na sekundę. PBKDF2 wykonuje HMAC(hasło, sól) w kółko — iter razy — więc każde zgadnięcie kosztuje tyle samo iter HMAC-ów, zarówno dla obrońcy, jak i dla atakującego. Domyślnie tu jest 600 000 iteracji z HMAC-SHA-256, bazowa wartość z OWASP Password Storage Cheat Sheet; suwak sięga dziesięciu milionów, bo zalecenia bezpieczeństwa rosną wraz z przyspieszaniem sprzętu.
Sól. Losowa sól dla każdego hasła oznacza, że identyczni użytkownicy nie mają już identycznych skrótów, a wcześniej obliczone tablice (tablice tęczowe) tracą wartość. Nie jest sekretna — jest przechowywana obok skrótu — musi tylko być unikalna. Normą są 16 losowych bajtów.
Znana słabość. PBKDF2 jest trudny obliczeniowo dla CPU, ale nie dla pamięci: GPU i ASIC zrównoleglają go znakomicie. Dlatego nowoczesne zalecenie to scrypt lub Argon2id tam, gdzie projektuje się przechowywanie skrótu hasła (strona Generatora skrótów haseł z tej rodziny je omawia), a PBKDF2 pozostaje właściwą odpowiedzią dla zgodności i ustawień FIPS-140.
Czym jest HKDF (RFC 5869)
Najpierw extract, potem expand. HKDF wykonuje dwa zadania. Extract: spłaszcza materiał klucza wejściowego, który może być nierówny (np. wspólny sekret Diffiego–Hellmana), wraz z solą w jeden krótki klucz pseudolosowy PRK = HMAC(salt, IKM). Expand: rozciąga PRK do dowolnej długości, do 255 bloków skrótu, przy czym każdy blok wyjściowy jest połączony z poprzednim i oznaczony polem info. Dzięki temu jeden sekret może bezpiecznie dać klucz szyfrujący, klucz MAC i IV, wszystkie rozdzielone.
Nie do haseł. HKDF zakłada, że jego wejście ma już pełną entropię — wykonuje jeden HMAC na 32 bajty wyjścia, więc hasło ludzkie przechodzi przez niego praktycznie natychmiast, czyli dokładnie tak, jak chce atakujący. Przepuszczanie haseł przez HKDF zamiast PBKDF2 to klasyczny błąd projektowy; pole info służy do etykiet przeznaczenia ("client traffic key", "server iv"), a nie do dodatkowej entropii.
Gdzie to występuje. TLS 1.3 wyprowadza każdy używany klucz z sekretu uzgadniania przez HKDF; WireGuard, Signal, EAP-TLS 1.3 i JSON Web Encryption (jako bezpośrednie KDF uzgadniania klucza) należą do tego samego drzewa rodzinnego.
Wartości kontrolne — odtwórz je na tej stronie
Pierwsze dwie tabele to wektory testowe, na których opierają się przycisk Próbka i autotest tej strony (klucz "key", wiadomość „The quick brown fox jumps over the lazy dog”; potem przypadek w stylu RFC: 16-bajtowy klucz 0x0b i wiadomość „Hi There”). Wszystkie zostały wygenerowane przez niezależną natywną implementację i ponownie zweryfikowane na tej stronie.
HMAC dla „fox”, klucz = key | Skrót (hex) |
| HMAC-MD5 | 80070713463e7749b90c2dc24911e275 |
| HMAC-SHA-1 | de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 |
| HMAC-SHA-256 | f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 |
| HMAC-SHA-384 | d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237 |
| HMAC-SHA-512 | b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a |
| Punkty kotwiczące KDF | Parametry | Wyjście (hex, pierwsze bajty) |
| PBKDF2-HMAC-SHA-1 | hasło / sól, c=4096, 32 bajty | 4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db |
| PBKDF2-HMAC-SHA-256 | hasło / sól, c=4096, 32 bajty | c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a |
| HKDF-SHA-256 (RFC 5869 A.1) | IKM=0x0b×22, sól=00..0c, info=f0..f9, L=42 | 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 |
| HKDF-SHA-256 (RFC 5869 A.2) | IKM=00..4f, sól=60..af, info=b0..ff, L=82 | b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c… |
| HKDF-SHA-256 (RFC 5869 A.3) | IKM=0x0b×22, pusta sól i info, L=42 | 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 |
Typowe błędy
- Mylenie HMAC z szyfrowaniem. HMAC dowodzi integralności i pochodzenia (przy współdzielonym sekrecie); niczego nie ukrywa. Każdy bez klucza nadal widzi całą wiadomość.
- Mylenie HMAC z podpisem. Podpisy cyfrowe są kluczem publicznym: jeden podpisuje, każdy weryfikuje. HMAC jest symetryczny: każdy weryfikator mógłby też sfałszować. Do niezaprzeczalności potrzebne są RSA/ECDSA (zobacz narzędzie RSA z tej rodziny, gdy zostanie opublikowane), a nie HMAC.
- Niezgodności w odczycie klucza. 64-znakowy ciąg hex wklejony do pola klucza tekstowego staje się 64 bajtami, a nie 32 — i HMAC zmienia się całkowicie. Ta strona wypisuje sposób odczytu w wierszu wyjścia; gdy dwa narzędzia się nie zgadzają, to pierwsza rzecz do porównania.
- Za mała liczba iteracji PBKDF2. 1000 iteracji było rozsądne w 2000 roku; dziś karty GPU zjadają to na śniadanie. Jeśli system wciąż przechowuje skróty z 1000 iteracjami, zaplanuj migrację przez ponowne haszowanie przy logowaniu.
- HKDF na haśle. Jeden HMAC na blok wyjściowy oznacza, że hasło przechodzi natychmiast — używaj PBKDF2 (lub Argon2id) do haseł, a HKDF do sekretów o wysokiej entropii.
- Ponowne użycie jednego wyprowadzonego klucza do wszystkiego. Rozwiązanie jest darmowe: wyprowadź osobne klucze z różnymi etykietami
info. Dwa klucze z jednego IKM z różnymi etykietami są z założenia niezależne.
FAQ
Czy HMAC-MD5 jest złamany? Jako skrót odporny na kolizje MD5 jest martwy, ale bezpieczeństwo HMAC-MD5 zależy od MD5 jako funkcji pseudolosowej, a nie znano praktycznego złamania. I tak jest wycofany — nie ma powodu, by wybrać go zamiast HMAC-SHA-256, poza zgodnością ze starym protokołem.
Jak długi powinien być mój klucz HMAC? Co najmniej tyle, ile wynosi rozmiar wyjścia skrótu (32 bajty dla SHA-256), i wygenerowany przez CSPRNG. Klucz krótszy od skrótu jest dozwolony, ale każdy bit poniżej tego progu bezpośrednio obniża bezpieczeństwo.
Czy PBKDF2 z większą liczbą iteracji staje się „bezpieczniejszy” bez końca? Podnosi koszt atakującego liniowo, ale także koszt logowania użytkowników, też liniowo. Chodzi o wybranie największej liczby, jaką twoi użytkownicy zniosą — do tego służą zalecenia OWASP.
Dlaczego HKDF jest ograniczony do 255 × rozmiar skrótu? Pętla rozszerzania to T(i) = HMAC(PRK, T(i-1) || info || i) z jednobajtowym licznikiem i — 255 to największa wartość licznika, twarde ograniczenie strukturalne RFC 5869, a nie wybór polityki.
Czym różni się PBKDF2 na tej stronie od Generatora skrótów haseł? Ten sam algorytm, inne zadanie. Ta strona wyprowadza surowe bajty klucza do użycia gdzie indziej; strona skrótów haseł tworzy ciągi przechowywanych poświadczeń (z osadzoną solą i parametrami) i weryfikuje wklejone kandydatury względem nich.