Encryption / Hash

PBKDF2 Key Derivation

Derive a fixed-length key from a passphrase and random salt with Web Crypto.

PBKDF2
Derived locally with Web Crypto; the passphrase is never uploaded.
Derived output
Hex
—
Base64
—

PBKDF2 Key Derivation

Derive fixed-length key material from a passphrase, salt, iteration count, and hash using the browser Web Crypto API. Inputs are not uploaded.

Security Notes

  • The salt and parameters are required to reproduce a key
  • Use a unique random salt; it is not a password
  • For new password-storage systems, evaluate Argon2id; this output is raw derived key material, not a complete password record

PBKDF2 turns a passphrase plus a salt into key material of a chosen bit length, repeating one HMAC call per iteration so each guess stays expensive. This page runs the derivation through Web Crypto, and a passphrase typed here never leaves the tab. It fits reproducing a stored PBKDF2 record, or turning a passphrase into an AES key.

What the construction actually computes

PBKDF2 is specified in RFC 8018 (PKCS #5 v2.1). The output is the concatenation of blocks T1, T2 and so on, each from an independent chain: the first HMAC runs over the salt followed by a 4-byte big-endian block index starting at 1, and every later round runs HMAC over the previous round. The block is then the XOR of all c of those values, where c is the iteration count. So one iteration equals one full HMAC call, the salt is used verbatim rather than padded, and a block is as wide as the hash digest: 32 bytes for SHA-256, 48 for SHA-384, 64 for SHA-512. The RFC caps derived length at (2^32 - 1) x hLen, a ceiling no browser interface comes near.

Why shorter key lengths are prefixes

The block counter always starts at 1 regardless of how many bits were requested, so a short derivation is a byte-for-byte prefix of a longer one. With the same passphrase and salt, a 192-bit result is the first 24 bytes of the 256-bit result, and 512 bit appends a second, separately chained block after those same 32 bytes. Two consequences matter. Choosing 128 bit does not yield a separate weaker key: whoever holds the 256-bit value already holds it. And 512 bit under SHA-256 runs two chains, so it costs roughly double, measured here at about 57 ms against 29 ms for 256 bit at 210,000 iterations. Pick the length the consumer needs, 128, 192 or 256 bit for AES, rather than over-deriving.

One iteration count is not equal work across hashes

The iterations field defaults to 210,000 and is validated as an integer between 1,000 and 2,000,000. Counts are only comparable inside a single hash function, because HMAC-SHA-384 and HMAC-SHA-512 process 128-byte blocks and encode lengths in 64 bits, so each call costs more: at 210,000 iterations the same machine needed about 51 ms for SHA-384 and 50 ms for SHA-512, against 29 ms for SHA-256, meaning 210,000 SHA-512 rounds buy roughly the work of 360,000 SHA-256 rounds. SHA-1 is deliberately missing, so records built on PBKDF2-HMAC-SHA1 must be re-derived elsewhere before migration. Either way, store the hash name, the hex salt and the count with the record; none of them is recoverable from the output.

Worked example

Default parameters, 256-bit output

Input
hunter2 / salt 00112233445566778899aabbccddeeff / SHA-256 / 210000 iterations / 256 bit
Output
ad519071e256cf0e45b48e4208a69a0d3a5fcf5db6d8cb26f1e9cf3758d46e49

Thirty-two bytes is exactly one SHA-256 block (hLen = 32), so the single counter value was enough and the hex is 64 characters. The Base64 panel shows the identical bytes as rVGQceJWzw5FtI5CCKaaDTpfz1222Msm8enPN1jUbkk=. Raising the length to 512 bit would leave these first 32 bytes unchanged and append a second block.

Limits and pitfalls

  • Iterations must be an integer from 1,000 to 2,000,000; anything outside that range fails before the derivation starts.
  • Derived length is limited to 128, 192, 256 or 512 bit, because Web Crypto takes a bit count — there is no arbitrary byte length and no 1,024-bit option.
  • The salt field takes even-length hex only, stripping a leading 0x and spaces; an empty field raises that same even-length error, and Base64 salts from other systems must be decoded first.
  • The output is text only, hex and Base64, with no handoff to the AES tool, so the hash name, salt and iteration count must be saved with it or the key cannot be reproduced.
  • The passphrase is encoded as UTF-8 with no Unicode normalization, so an accented letter typed as U+00E9 and as U+0065 U+0301 derives different keys.

Related tools

Reproducing a stored record here, or routing it somewhere else

DecisionThis PBKDF2 toolAlternative route
The record uses SHA-1, or a key longer than 512 bitImpossible to match: the hash list is SHA-256, SHA-384 and SHA-512 only, and the length list stops at 128, 192, 256 and 512 bit, so the derived bytes can never line up with such a record.Go to a library: hashlib.pbkdf2_hmac("sha1", pw, salt, iterations, dklen=128) in Python, or Node crypto.pbkdf2Sync with a hash name and byte length of your choosing. Both take any digest name and any output size.
You want the raw key behind a ciphertext made by this site’s AES toolMatch its fixed constants: SHA-256, 100000 iterations, 256 bit. Its output is unpadded Base64URL with the 16-byte salt in front, so the salt goes back in as 32 hex characters before anything can be compared.The AES tool itself, which derives that key and never displays it: it can decrypt with the passphrase alone. Only extract the key when a second system has to encrypt with it too.
You are choosing parameters for a login table you ownFine for reproducing single records, but the count cannot exceed 2,000,000 and nothing is scripted: one passphrase, one click, one key.Do the hashing in the signup handler, where the library call can run 600,000 SHA-256 rounds (the OWASP floor) or argon2id and write the salt and count into the same row. A page in a browser is not a place to hash 40,000 passwords.
You only need to know whether a file or message changedThe wrong instrument: the default 210,000 HMAC rounds exist to make guessing slow, and you would also have to remember the salt and count to reproduce the value later.Hash tool for a bare digest, or HMAC tool when a secret must be involved — one pass each, no salt to store, and the output is still comparable months later.
The salt arrives Base64 rather than hex, the shape most hashing libraries emitOnly even-length hex gets through, so most Base64 strings are rejected outright. The dangerous ones are Base64 strings drawn entirely from 0-9 and a-f: they pass the check and derive a key from the wrong bytes with no error shown.Decode before pasting: printf %s "<b64>" | openssl base64 -d | xxd -p. Do not route a binary salt through the site’s Base64 tool, because its decode path reads the bytes as UTF-8 text and fails on anything that is not valid text.
You are unsure whether the passphrase itself is good enoughAny non-empty string is accepted, including abc; the page checks only that the field is not blank, so it will happily derive a key from four characters.Password checker first, then come back. No iteration count on this page repairs a guessable passphrase, and 2,000,000 rounds of a dictionary word is still a dictionary word.

One concrete scenario

Reading the bit length back out of a vendor digest

A vendor ships 40,000 rows shaped pbkdf2_sha256$210000$<32 hex chars>$<88 Base64 chars> and none of them verify. Count first. The salt field is 32 hex characters, 16 bytes, and goes in unchanged. The digest ends in ==: 88 Base64 characters hold 64 bytes, so the length setting must be 512 bit, not the 256 default, while 210000 iterations already sit inside the accepted range. A correct passphrase then prints 128 hex characters, two per byte. A digest ending in one = spans 44 characters, 32 bytes, and needs 256 bit instead; choosing 512 there appends a block the row never stored, and 128 characters against 64 sends you chasing a salt fault that does not exist.

Frequently Asked Questions

How many iterations should I use?
Iterations exist to slow brute force. OWASP 2023 recommends at least 600,000 for PBKDF2-HMAC-SHA256; a practical target is ~250–500 ms per verification on your hardware — imperceptible to users, devastating to attackers. Store the iteration count with the salt and raise it over time.
Do the salt and iteration count need to stay secret?
No — both are stored in the clear alongside the hash. The salt defeats rainbow tables and identical-password correlation; it is not a secret. The only secret is the user’s password itself.
PBKDF2, bcrypt, or Argon2?
Argon2id for new systems (memory-hard, resists GPUs and ASICs); bcrypt for compatibility; PBKDF2 where FIPS certification or Web Crypto’s native support matters — this tool uses the latter, well suited for deriving encryption keys or matching existing systems rather than designing new password storage.

Content reviewed: