Jelszó-hash-generátor és -ellenőrző

Jelszavak hash-elése és ellenőrzése bcrypt, scrypt, Argon2id és PBKDF2 eljárással teljes egészében a böngészőben — PHC-formátumú karakterláncok készítése, meglévő hash ellenőrzése egy jelölt jelszóval, és a benne rejlő paraméterek vizsgálata. Semmi nem kerül feltöltésre.
Csak teszt-jelszavakhoz. Valódi felhasználói jelszavakat soha nem szabad egyetlen weboldalba sem beilleszteni. Ez az eszköz teljes egészében a böngészőben fut — a karakterláncok soha nem hagyják a lapot —, de egy valódi adatszivárgás egyetlen beillesztéssel kezdődik.
bcrypt költség (2^költség kör)
bcrypt-variáns a variáns csak az előtagot változtatja; a hash értéke azonos
scrypt N (CPU-költség)
scrypt r / p r =   p = blokkméret 128·r bájt; memória = 128·N·r bájt (N=214, r=8 → 16 MiB)
Argon2id m (memória)
Argon2id t / p t =   p = t = menetek; p = párhuzamosság (sávok)
PBKDF2 PRF
PBKDF2-iterációk  OWASP 2023: 600 000 HMAC-SHA-256-hoz (1 300 000 SHA-1-hez, 210 000 SHA-384/512-höz)
Kimeneti hossz (bájt)  A bcrypt kimenete rögzítetten 23 bájt (31 bcrypt-base64 karakter)
AlgoritmusParaméterekMemóriaKimeneti hosszIdő (ebben a böngészőben)
bcryptköltség 124 KiB23 bájt-
scryptN=214, r=8, p=116 MiB32 bájt-
Argon2idm=19 MiB, t=2, p=119 MiB32 bájt-
PBKDF2HMAC-SHA-256, 600 000 iteráció~032 bájt-
Paraméter-puskalap (OWASP Password Storage Cheat Sheet, 2023-as minimumok)
AlgoritmusMinimumMegjegyzések
Argon2idm = 19 MiB (19 456 KiB), t = 2, p = 1előnyben részesített; memóriaigényes
scryptN = 214, r = 8, p = 1memóriaigényes (minimum 16 MiB)
bcryptköltség = 10csak munkafaktor; 72 bájtos jelszókorlát
PBKDF2-HMAC-SHA256600 000 iterációcsak iterációs keménység — GPU-barát, utolsó választás
Az oldal alapértékei minden minimumnak megfelelnek vagy azt meghaladják. Éles környezetben először az Argon2id javasolt; ha nem elérhető, a scrypt vagy a bcrypt; a PBKDF2 csak FIPS-megfelelési okból.
PHP-együttműködés — a password_hash($pw, PASSWORD_BCRYPT) $2y$10$... alakot ad: beilleszthető az Ellenőrzés mezőbe a jelölt jelszóval, és ez az oldal pontosan azt válaszolja, amit a password_verify() válaszolna. A PASSWORD_ARGON2ID kimenete ($argon2id$v=19$m=65536,t=4,p=1$...) is ellenőrizhető. A passlib, a django-argon2 és a crypto.scrypt-burkolás PHC-karakterláncait is elemzi.
Önteszt
Újrafuttatja az oldal motorját nyilvános vektorokon: a bcrypt crypt_blowfish tesztkészletén, a node/OpenSSL által generált scrypt- és Argon2id-karakterláncokon, az RFC 6070 PBKDF2-vektorain és a nyilvános SHA-256-készleten, valamint minden algoritmuson generálás-majd-ellenőrzés körutazásokon és negatív teszteken (rossz jelszónak el kell buknia, a hibás karakterláncokat el kell utasítani). Semmi nem kerül elküldésre.
Jelszó-hash-elés a nulláról magyarázva
Egy mondatban: a jelszó-hash szándékosan lassú (és lehetőleg memóriaigényes), hogy az adatbázis ellopása ne engedje a támadónak, hogy másodpercenként milliárdnyi találgatást próbáljon — ez ellentéte a gyors hash, például a SHA-256 céljának, amelyet sebességre terveztek.
Miért nem elég egyszerűen SHA-256-tal hash-elni a jelszót?

A SHA-256 modern GPU-n másodpercenként milliárdnyi találgatást fut. Egy 8 karakteres jelszónak jóval 1013 alatti kombinációja van — órányi GPU-idő, nagy rendszeren percek. A jelszó-hash függvények (KDF-ek) költségparaméterekkel küzdenek ez ellen: a bcrypt a magját 2költség-szor ismétli, a PBKDF2 a HMAC-et több százezerszer iterálja, a scrypt és az Argon2id pedig találgatásonként megabájtnyi memóriát igényel, így a GPU-k (gyorsak, de magonként kevés memóriával) elvesztik előnyüket. A só — véletlen, és nyíltan tárolódik a hash-karakterláncban — megakadályozza az előre kiszámított szivárványtáblákat, és minden találgatást felhasználónként újra kell számolni.

Az oldal négy algoritmusa
AlgoritmusÉvKeménységAláírási formátumVigyázni kell rá
bcrypt1999CPU (2költség kulcsbeállítás)$2b$12$ + 22 karakteres só + 31 karakteres hash72 bájtos jelszókorlát (a 72-n túli rész csendben figyelmen kívül marad); a NUL-bájt az eredeti C-implementációban véget vet a jelszónak
PBKDF22000 (RFC 2898/8018)CPU (iterációk)$pbkdf2-sha256$i=600000$ + só + hash (passlib-stílus)nincs memóriaköltség — a GPU-k és ASIC-ek kedvelik; csak az iterációszám állítható
scrypt2009 (RFC 7914)CPU + memória (128·N·r bájt)$scrypt$ln=14,r=8,p=1$ + só + hashN kettő hatványa kell legyen; a memória r-rel lineárisan nő
Argon2id2015 (PHC-győztes, RFC 9106)CPU + memória (m KiB, t menet)$argon2id$v=19$m=19456,t=2,p=1$ + só + hashArgon2i (adatfüggetlen) vs. Argon2d (adatfüggő) vs. Argon2id (hibrid) — mindig az id változat javasolt, hacsak nincs ok, amiért nem
Memóriakeménység vs. számítási keménység

A GPU-nak ezer magja van, de minden magnak csak kevés gyors memóriája. Az a KDF, amely jelszavanként 19 MiB munkakészletet igényel, az támadót annyi párhuzamos találgatásra korlátozza, ahány 19 MiB-os memóriadarabja van — ezért lehet az Argon2id 19 MiB-on a gyakorlatban erősebb, mint a bcrypt 15-ös költségen, annak ellenére, hogy a laptopon kevesebb idő alatt fut. A PBKDF2-nek nincs erre válasza: az egyetlen szabályozója az iterációszám, a szilícium pedig ezt lineárisan skálázza.

PHC-karakterlánc olvasása

A moduláris-crypt / PHC-formátum önleíró: a $argon2id$v=19$m=19456,t=2,p=1$ICEiIyQlJicoKSorLC0uLw$WTGpK4hf... karakterláncban a mezők: algoritmus, verzió, paraméterek (m = memória KiB-ban, t = menetek, p = sávok), base64-só, base64-hash. A bcrypt megelőzi a szabványt, és saját tömör formát használ: $2b$ variáns, 12 költség, majd só és hash a bcrypt saját base64-ábécéjében (./A-Za-z0-9). Ez az oldal ellenőrzése mindezeket elfogadja, és megmutatja az elemzett mezőket — bármely talált hash beilleszthető, és megtekinthető, mire bomlik.

Gyakori hibák
  • Gyors hash jelszavakhoz. Az MD5/SHA-1/SHA-256 jelszóoszlopok másodpercenként milliárdnyi találgatással, kereskedelmi GPU-kon törhetők fel. Fájlokhoz és adatokhoz a Hash-generátor használható; jelszavakhoz ennek az oldalnak az algoritmusai.
  • Só megosztása. Egy só minden felhasználónak azt jelenti, hogy az azonos jelszavak azonos hash-t kapnak, és a szivárványtáblák visszatérnek. Minden itteni hash friss, 16 bájtos véletlen sót kap.
  • A bcrypt 72 bájtjának figyelmen kívül hagyása. A "a"*100 és a "a"*72 azonos hash-t ad — a farok elvész. Az oldal a beviteli mezőnél figyelmeztet, ha a jelszó 72 bájtnál hosszabb. Az Argon2-nek nincs ilyen korlátja.
  • Hash-ek összehasonlítása ==-vel a kódban. Az ellenőrzésnek konstans idejűnek kell lennie; az oldal motorja ezt belsőleg megteszi (újraszámolja, majd összeveti a tárolt bájtokat), de ha a módszert másolja, konstans idejű összehasonlítás alkalmazandó.
  • Paraméterek hangolása gyors fejlesztői gépen. A cél kb. 250–500 ms hash-elési idő a termelési felhasználók mediánhardverén, nem a munkaállomáson. A Benchmark gomb megmutatja, mit tapasztal ez a böngésző.
  • Újra-hash-elés minden bejelentkezési ellenőrzésnél. Először az ellenőrzés fut le; csak sikeres ellenőrzés után következik az újra-hash-elés (például a költség növeléséhez), és az új karakterlánc tárolandó. A PHP password_needs_rehash() függvénye éppen erre szolgál.
GYIK

Melyiket válasszam? Argon2id az OWASP-minimumokkal legalább. Ha a futtatókörnyezet nem kínálja: scrypt, majd bcrypt (olyan költséggel, hogy a hash-elés ≥250 ms legyen). A PBKDF2-t csak ott, ahol a tanúsítás megköveteli.

Miért látható a kimeneti karakterláncban véletlen só? A só nem titok — szándékosan nyíltan tárolódik a PHC-karakterláncban, így az ellenőrzéshez csak a karakterlánc és a jelölt jelszó kell. Feladata az egyediség, nem a titkosság.

Számít a variáns ($2a$ / $2b$ / $2y$)? ASCII-jelszavaknál azonos hash-t adnak; a $2a$ az 1990-es eredeti, a $2b$ egy ritka előjel-kiterjesztési hibát javított (2014), a $2y$ pedig a PHP jelölése arra, hogy a javítás jelen van. Az ellenőrzés mindhármat elfogadja.

Mennyi ideig tart egy hash? Nagyjából 250–500 ms bejelentkezésenként szerver-hardveren. 100 ms alatt az offline feltörés olcsó; 1 mp fölött a felhasználók panaszkodnak, mielőtt a biztonság javulna.

Ellenőrizhetek máshol generált hash-t? Igen — beilleszthető, és a jelölt jelszó megadható. Ismert jó formátumok: a PHP password_hash (bcrypt $2y$ és Argon2id), a Python passlib, a django argon2 hasher és a Tarsnap scrypt eszköze által használt scrypt karakterláncformátum.

Mit csinál a „benchmark” gomb? Az aktuális jelszót egyszer hash-eli minden algoritmussal az oldal alapparamétereivel, és a böngészőben mért időt jelenti — érzés a költségkülönbségekről, nem szigorú mérés.