Az első sor rögzíti a pontos használt paramétereket (algoritmus, olvasat, bemeneti méretek), így a másolt eredmény mindig reprodukálható.
HMAC, PBKDF2 és HKDF — a kulcsos kivonatolás nulláról elmagyarázva
Egy mondatban: egy puszta hash, például a SHA-256, bárki kiszámíthatja, ezért semmit nem bizonyít arról, ki küldött egy üzenetet — a HMAC titkos kulcsot kever be, így csak a kulcs birtokosai tudják létrehozni (vagy ellenőrizni) a kivonatot; a PBKDF2 és a HKDF ugyanezt a HMAC-gépezetet használja arra, hogy a titkokból kulcsok legyenek: jelszavaknál lassan, már véletlen anyagnál gyorsan.
Mi a HMAC (RFC 2104)
A felépítés. A HMAC nem egy, hanem két kivonatfutás. A kulcs a kivonat blokkméretére van kitöltve (64 bájt az MD5/SHA-1/SHA-256 esetén, 128 a SHA-384/512 esetén); az üzenetet egyszer a kulcs és egy rögzített belső pad XOR-jával kivonatolják, ezt a kivonatot pedig újra a kulcs és egy rögzített külső pad XOR-jával. Ez a dupla szendvics bizonyíthatóan biztonságos, amíg az alap kivonat tisztességes pszeudorandom függvény — ezért ellenáll még a HMAC-MD5 a gyakorlati ütközési támadásoknak, amelyek a sima MD5-öt megtörték (bár alább látni fogjuk, hogy visszavonták).
Kulcsok. Bármilyen kulcshossz működik: a blokkméretnél rövidebb kulcs változatlanul használódik (de 32 bájt alatt kifogásolható), a hosszabbat előbb kivonatolják. Az oldal a kulcsot szövegként, hexként vagy Base64-ként engedi megadni, így egy 64 hex-karakteres éles kulcs beilleszthető anélkül, hogy valaki 64 karakteres szöveges jelszónak nézné — az olvasatot pontosan ezért rögzíti a kimeneti sor.
Hol találkozik vele az ember. A JWT fejlécének HS256 mezője szó szerint a base64url-kódolt token részein képzett HMAC-SHA-256 (az oldalon lévő JWT-dekóder pontosan ezt számolja, ha HS256 titkot illesztenek be). A webhook-aláírások (Stripe, GitHub), az AWS SigV4, a régebbi TLS-rekordvédelem és az OpenSSH umac-64@openssh.com rokona mind ugyanebbe a családba tartoznak.
Miért nem elég a hash(üzenet || kulcs)? Hosszkiterjesztés: az MD5/SHA-1/SHA-2 család minden kivonata lehetővé teszi, hogy aki ismeri a H(titok || üzenet) értéket, kiszámítsa a H(titok || üzenet || kitöltés || bármi) értéket a titok ismerete nélkül. A HMAC belső/külső felosztása ezt a támadási osztályt megszünteti. Ez a legelterjedtebb barkácsolt hiba az API-aláírási kódokban — és ezért létezik a HMAC.
Mi a PBKDF2 (RFC 8018)
Szándékosan lassú. Egy jelszónak talán 40 bit valódi entrópiája van; a támadó GPU-ja másodpercenként milliárd nyers SHA-256-ot próbál. A PBKDF2 a HMAC(jelszó, só) műveletet újra és újra futtatja — iter-szer — így minden találgatás ugyanannyi iter HMAC-be kerül a védekezőnek, mint a támadónak. Az alapérték itt 600 000 iteráció HMAC-SHA-256-tal, az OWASP Password Storage Cheat Sheet alapvonala; a csúszka tízmillióig megy, mert a biztonsági ajánlások felfelé mozdulnak, ahogy a hardver gyorsul.
Só. Jelszavanként véletlen só miatt az azonos felhasználók már nem azonos kivonatot kapnak, és az előre kiszámított táblázatok (szivárványtáblák) használhatatlanná válnak. Nem titkos — a kivonat mellett tárolódik — csak egyedinek kell lennie. A 16 véletlen bájt a szokásos.
Ismert gyengeség. A PBKDF2 CPU-igényes, de nem memóriaigényes: a GPU-k és ASIC-ek kiválóan párhuzamosítják. Ezért a modern tanács az scrypt vagy az Argon2id, ahol jelszókivonat-tárolást terveznek (ebben a családban a Jelszókivonat-generátor oldal tárgyalja őket), a PBKDF2 pedig továbbra is a helyes válasz a kompatibilitáshoz és a FIPS-140 beállításokhoz.
Mi a HKDF (RFC 5869)
Kinyerés, majd kibontás. A HKDF két feladatot lát el. Kinyerés: a talán egyenetlen bemeneti kulcsanyagot (például egy Diffie–Hellman megosztott titkot) egy sóval együtt egyetlen rövid, pszeudorandom kulcsba préseli: PRK = HMAC(salt, IKM). Kibontás: a PRK-t bármilyen 255 kivonatblokkig terjedő hosszúságra nyújtja, úgy, hogy minden kimeneti blokk az előzőhöz láncolódik, és a info mező címkézi. Ennek eredményeként egyetlen titokból biztonságosan kapható egy titkosítási kulcs, egy MAC-kulcs és egy IV, mind elkülönítve.
Nem jelszavakra. A HKDF feltételezi, hogy a bemenete már teljes entrópiájú — kimeneti 32 bájtonként egy HMAC-et végez, így az emberi jelszó gyakorlatilag azonnal átmegy rajta, pontosan amit a támadó szeretne. Jelszavak HKDF-en át PBKDF2 helyett klasszikus tervezési hiba; az info mező célcímkéknek ("client traffic key", "server iv") való, nem extra entrópiának.
Hol találkozik vele az ember. A TLS 1.3 a handshake-titokból a HKDF-fel származtat minden kulcsot; a WireGuard, a Signal, az EAP-TLS 1.3 és a JSON Web Encryption (közvetlen kulcsegyeztető KDF-ként) mind ugyanazon a családfán szerepelnek.
Ellenőrző értékek — ezen az oldalon állíthatók elő
Az első két táblázat azok a tesztvektorok, amelyekre az oldal Minta gombja és önellenőrzése épül (kulcs "key", üzenet „The quick brown fox jumps over the lazy dog”; majd a 16 bájtos 0x0b kulcs és az „Hi There” üzenet RFC-stílusú esete). Mindegyiket független, natív megvalósítás állította elő, és ezen az oldalon újraellenőrizték.
A „fox” HMAC-je, kulcs = key | Kivonat (hex) |
| HMAC-MD5 | 80070713463e7749b90c2dc24911e275 |
| HMAC-SHA-1 | de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 |
| HMAC-SHA-256 | f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 |
| HMAC-SHA-384 | d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237 |
| HMAC-SHA-512 | b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a |
| KDF-horgonyok | Paraméterek | Kimenet (hex, első bájtok) |
| PBKDF2-HMAC-SHA-1 | jelszó / só, c=4096, 32 bájt | 4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db |
| PBKDF2-HMAC-SHA-256 | jelszó / só, c=4096, 32 bájt | c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a |
| HKDF-SHA-256 (RFC 5869 A.1) | IKM=0x0b×22, só=00..0c, info=f0..f9, L=42 | 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865 |
| HKDF-SHA-256 (RFC 5869 A.2) | IKM=00..4f, só=60..af, info=b0..ff, L=82 | b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c… |
| HKDF-SHA-256 (RFC 5869 A.3) | IKM=0x0b×22, üres só és info, L=42 | 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8 |
Gyakori hibák
- A HMAC összetévesztése a titkosítással. A HMAC az integritást és az eredetet bizonyítja (megosztott titok esetén); semmit nem rejt el. Aki nem ismeri a kulcsot, továbbra is látja a teljes üzenetet.
- A HMAC összetévesztése az aláírással. A digitális aláírások nyilvános kulcsúak: az egyik aláír, bárki ellenőriz. A HMAC szimmetrikus: minden ellenőrző hamisíthatna is. A letagadhatatlansághoz RSA/ECDSA kell (részletek: ebben a családban az RSA-eszközt, amint megjelenik), nem HMAC.
- Kulcsolvasási eltérések. Egy 64 karakteres hex-sztring a Szöveg kulcsmezőbe illesztve 64 bájt lesz, nem 32 — és a HMAC teljesen megváltozik. Az oldal a kimeneti sorban kiírja az olvasatot; ha két eszköz nem ért egyet, ezt kell először összevetni.
- Túl alacsony PBKDF2-iteráció. 1000 iteráció 2000-ben ésszerű volt; ma a GPU-s rendszerek felfalják. Ha a rendszer még mindig 1000 iterációs kivonatokat tárol, bejelentkezéskor újrakivonatoló migrációt érdemes tervezni.
- HKDF jelszón. Kimeneti blokkonként egy HMAC: a jelszó azonnal átmegy rajta — jelszavakhoz PBKDF2 (vagy Argon2id), magas entrópiájú titkokhoz HKDF alkalmazandó.
- Egy származtatott kulcs újrahasználása mindenre. A javítás ingyenes: különböző
info címkékkel külön kulcsok származtathatók. Egy IKM-ből különböző címkékkel származtatott két kulcs tervezés szerint független.
GYIK
Törött a HMAC-MD5? Ütközésálló kivonatként az MD5 halott, de a HMAC-MD5 biztonsága az MD5-nek pszeudorandom függvényként való viselkedésétől függ, és ismert gyakorlati törés nincs rá. Mindenesetre visszavonták — a HMAC-SHA-256 helyett csak egy régi protokollal való kompatibilitás miatt érdemes választani.
Mekkora legyen a HMAC-kulcsom? Legalább a kivonat kimeneti mérete (32 bájt a SHA-256-nál), és kriptográfiailag biztonságos véletlenszám-generátorral előállítva. A kivonatnál rövidebb kulcs megengedett, de minden ez alatti bit közvetlenül csökkenti a biztonságot.
Biztonságosabb-e a PBKDF2 a végtelenségig, ha több iteráció van? A támadó költségét lineárisan növeli, de a bejelentkezés költségét is lineárisan. A feladat a legnagyobb olyan darabszám kiválasztása, amelyet a felhasználók még elviselnek — ezekre az értékekre kalibrálják az OWASP számait.
Miért korlátozott a HKDF 255 × kivonatméretre? A kibővítő ciklus T(i) = HMAC(PRK, T(i-1) || info || i) alakú, egybájtos i számlálóval — a 255 a legnagyobb számlálóérték, az RFC 5869 kemény szerkezeti korlátja, nem szabálykérdés.
Mi a különbség az oldal PBKDF2-je és a Jelszókivonat-generátor között? Ugyanaz az algoritmus, más feladat. Ez az oldal nyers kulcsbájtokat állít elő, amelyeket máshol lehet felhasználni; a jelszókivonat-oldal tárolt hitelesítő-sztringeket készít (beágyazott sóval és paraméterekkel), és a beillesztett jelöltöket ezek ellen ellenőrzi.