Tools · Passwords, passphrases and randomness
PBKDF2 calculator
Password, salt, iterations, hash and length in, key out. Loads the RFC 6070 and 7914 test vectors so you can check it.
This uses your browser's own PBKDF2 and sends nothing anywhere. Even so, do not paste a real password into any website; use a throwaway one to learn how it works.
This PBKDF2 calculator turns a password and a salt into a key using your browser's own PBKDF2, the same call cipher.ink makes to turn a passphrase into an encryption key. Set the hash, the iteration count and the key length, and check the output against the published test vectors below. Nothing is sent anywhere.
What PBKDF2 does
PBKDF2 (Password-Based Key Derivation Function 2, RFC 8018) stretches a password and a salt into a key of whatever length you ask for. It runs a keyed hash, HMAC, over the password and salt, feeds each result back through HMAC again for as many iterations as you set, and combines all the rounds with XOR. For the first block of the key:
U1 = HMAC(password, salt ‖ 00 00 00 01)
U2 = HMAC(password, U1)
...
Uc = HMAC(password, Uc-1)
T1 = U1 ⊕ U2 ⊕ ... ⊕ UcIf you ask for more bytes than one hash output holds (20 for SHA-1, 32 for SHA-256, 64 for SHA-512), it computes a second block the same way with the counter 00 00 00 02, and so on, then joins the blocks. The 64-byte SHA-256 test above is two blocks. The browser's Web Crypto API (deriveBits) does all the computing.
Check it against the published test vectors
The buttons load known answers so you can see the tool agrees with the standards. cipher.ink's automated tests also check these values every time the site is deployed.
| Source | Password, salt | Rounds | Hash | Derived key (hex) |
|---|---|---|---|---|
| RFC 6070 | password, salt | 1 | SHA-1 | 0c60c80f961f0e71f3a9b524af6012062fe037a6 |
| RFC 6070 | password, salt | 2 | SHA-1 | ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957 |
| RFC 6070 | password, salt | 4,096 | SHA-1 | 4b007901b765489abead49d926f721d065a429c1 |
| Widely published | password, salt | 1 | SHA-256 | 120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b |
| Widely published | password, salt | 4,096 | SHA-256 | c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a |
RFC 7914 section 11 gives a 64-byte SHA-256 vector (password passwd, salt salt, 1 round) that starts 55ac046e56e3089f, and its button loads it.
Choosing the salt, the rounds and the length
The salt must be different for every password and doesn't need to be secret. It stops two people with the same password from ending up with the same key, and it means an attacker can't use one precomputed table against everyone (salt and pepper explained). cipher.ink makes a fresh random 16-byte salt for every message.
The rounds are the dial that makes each guess slow. For PBKDF2-HMAC-SHA256, OWASP's cheat sheet currently recommends 600,000, which is what cipher.ink uses (why 600,000). Try the button for it and compare the time with 1,000 rounds. The benchmark does that for several counts at once.
The length should be whatever the key needs, which is 32 bytes for an AES-256 key. Asking for more output than the hash gives (say 64 bytes from SHA-256) makes the derivation twice as slow for you. An attacker checking guesses only has to compute the first 32 bytes to rule a guess out, so the extra length costs you and not them. That's a known pitfall of PBKDF2 with long outputs.
Common questions
Why does my result differ from another site's?
Usually the inputs differ in bytes you can't see. Look for a trailing newline in the password, a salt entered as text on one site and hex on the other, or a different hash. Hex input is the safest way to be exact. Check the length too, because the same inputs with a different length give a key that starts the same but runs longer or shorter.
Is SHA-1 safe here?
PBKDF2-HMAC-SHA1 doesn't rely on SHA-1 being collision-resistant, and the RFC 6070 vectors are for it. SHA-256 or SHA-512 is still the better choice today, and cipher.ink uses SHA-256.
Is PBKDF2 the best choice for storing passwords?
It's the one every browser has built in, and it's on the approved lists. For new systems with a choice, memory-hard functions such as Argon2id are stronger against graphics cards. See bcrypt, scrypt, Argon2 and PBKDF2 compared.
Can I get the same key somewhere else to check?
Yes. Python has hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 4096, 32).hex() and OpenSSL has openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:password -kdfopt salt:salt -kdfopt iter:4096 PBKDF2. Both give the 4,096-round SHA-256 value in the table (OpenSSL prints it in capitals with colons between the bytes).