HMAC, PBKDF2 & HKDF-számológép

Kiszámítható egy kulcsos üzenethitelesítő kód HMAC-MD5, HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-384 vagy HMAC-SHA-512 (RFC 2104) értéke szövegre, hex-bájtokra vagy teljes fájlokra — a kulcsok szövegként, hexként vagy Base64-ként adhatók meg. Vagy kulcsok származtathatók PBKDF2 (RFC 8018) és HKDF (RFC 5869) segítségével. Minden eredmény megjeleníthető hexként, nagybetűs hexként, Base64-ként vagy Base64url-ként. Egyszerű kivonatokhoz a Kivonatgenerátor, ellenőrző összegekhez a CRC-számológép, a JWT-ken belül használt HMAC-hoz pedig a JWT-dekóder való.
Teljes egészében helyben fut — a kulcsok és az üzenetek soha nem hagyják el a lapot. Legfeljebb 200 MB-os fájlok.
Felépítés: Kimenet:
HMAC-algoritmus: RFC 2104 — az MD5-változathoz md5.js szükséges (ezt az oldal tölti be).
A hex olvasása elfogadja a szóközöket, a kettőspontokat és a 0x előtagokat; a Base64 szabványos alakban, kitöltéssel vagy anélkül kell legyen.
Az üres kulcs az RFC 2104 szerint érvényes, de szinte mindig hiba — kulcs nélküli HMAC csak lassú kivonat.
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ó.
Melyik felépítésre van szükség?
A HMAC egy megosztott titokból és egy üzenetből hitelesítőt készít: a kulcsot ismerő fogadó újraszámolhatja, és észlelheti a manipulációt. Ez a „HS256” minden aláírt JWT-ben (részletek: a JWT-dekódert), és a világ API-kérés-aláírási sémáinak felében. A PBKDF2 emberi jelszó kulccsá nyújtására szolgál: a HMAC-et ezerszer ismétli, így minden jelszótipp a támadónak ugyanannyi késleltetésbe kerül. A HKDF protokollkulcsokhoz való: már véletlen titkos bájtokat vesz (például egy DH-megosztott titkot), és biztonságosan több célhoz kötött kulcsra bontja őket — a TLS 1.3 minden forgalmi kulcsát így származtatja. Hüvelykujjszabály: hitelesítés → HMAC; jelszó → PBKDF2 (vagy scrypt/Argon2, részletek: a Jelszókivonat-generátort, amint megjelenik); egyenletes titok → HKDF.
Önteszt
Az oldal motorjait a közzétett vektorokon futtatja: 10 HMAC-horgony (RFC 2202/4231-stílusú, öt algoritmus × két bemenet), 6 PBKDF2-horgony (SHA-1 és SHA-256 három iterációszámon), valamint az RFC 5869 négy HKDF-tesztesete, A.1–A.4. Semmi nem kerül elküldésre.
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 = keyKivonat (hex)
HMAC-MD580070713463e7749b90c2dc24911e275
HMAC-SHA-1de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC-SHA-256f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC-SHA-384d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237
HMAC-SHA-512b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a
KDF-horgonyokParaméterekKimenet (hex, első bájtok)
PBKDF2-HMAC-SHA-1jelszó / só, c=4096, 32 bájt4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db
PBKDF2-HMAC-SHA-256jelszó / só, c=4096, 32 bájtc5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a
HKDF-SHA-256 (RFC 5869 A.1)IKM=0x0b×22, só=00..0c, info=f0..f9, L=423cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
HKDF-SHA-256 (RFC 5869 A.2)IKM=00..4f, só=60..af, info=b0..ff, L=82b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c…
HKDF-SHA-256 (RFC 5869 A.3)IKM=0x0b×22, üres só és info, L=428da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
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.