{"id":"pbkdf2-compute","version":"1.0.0","description":"Derive a key from a password and salt with PBKDF2-HMAC-SHA1/256/384/512 (RFC 8018), within a hard CPU work-unit budget.","supported_operations":["pbkdf2 key derivation","derive a key from a password with pbkdf2-sha256","pbkdf2-hmac-sha256 test vector with 4096 iterations","pbkdf2-hmac-sha1 test vector","derive an encryption key from a passphrase","גזור מפתח מסיסמה עם pbkdf2"],"unsupported_operations":["production password-hash storage at real-world cost (bcrypt, Argon2id, or PBKDF2 at 600,000+ iterations) -- the CPU budget below caps far short of that","HKDF-style extract/expand key derivation (see hkdf-compute)"],"semantics":["algorithm selects the PRF, HMAC-Hash; HashLen is 20 (sha1), 32 (sha256), 48 (sha384) or 64 (sha512) bytes.","Algorithm (RFC 8018 section 5.2): let l = ceil(length / HashLen); for each block i = 1..l, U_1 = HMAC-Hash(password, salt || INT_32_BE(i)), U_j = HMAC-Hash(password, U_{j-1}) for j = 2..iterations, T_i = U_1 XOR ... XOR U_iterations. DK is T_1 || T_2 || ... || T_l truncated to exactly `length` bytes.","work_units = iterations * ceil(length / HashLen), the number of PRF calls per derived-key block times the block count -- it bounds the PRF work. The hard cap is work_units <= 4096 for sha1/sha256 and <= 1024 for sha384/sha512; exceeding it is limit_exceeded with details {limit}.","length is 1..1024 bytes (max_length); length > 1024 is limit_exceeded with details {limit: 1024}, checked before work_units.","password and salt are never echoed anywhere in the output or in any error's details.","hex is lowercase; base64 is RFC 4648 section 4 padded."],"limits":{"max_password_bytes":4096,"max_salt_bytes":4096,"max_length":1024,"max_work_units_sha1_sha256":4096,"max_work_units_sha384_sha512":1024},"pricing":{"status":"unpriced","charge_usd":null},"input_schema":{"type":"object","additionalProperties":false,"required":["password","salt","algorithm","iterations","length"],"properties":{"password":{"type":"string","maxLength":4096},"password_encoding":{"type":"string","enum":["utf8","hex","base64","base64url"],"default":"utf8"},"salt":{"type":"string","maxLength":4096},"salt_encoding":{"type":"string","enum":["utf8","hex","base64","base64url"],"default":"utf8"},"algorithm":{"type":"string","enum":["sha1","sha256","sha384","sha512"]},"iterations":{"type":"integer","minimum":1},"length":{"type":"integer","minimum":1,"maximum":1024}}},"output_schema":{"type":"object","additionalProperties":false,"required":["algorithm","hex","base64","length","iterations","work_units"],"properties":{"algorithm":{"type":"string","enum":["sha1","sha256","sha384","sha512"]},"hex":{"type":"string","pattern":"^[0-9a-f]+$","minLength":2},"base64":{"type":"string"},"length":{"type":"integer","minimum":1,"maximum":1024},"iterations":{"type":"integer","minimum":1},"work_units":{"type":"integer","minimum":1}}},"examples":[{"input":{"password":"password","salt":"salt","algorithm":"sha1","iterations":1,"length":20},"output":{"algorithm":"sha1","hex":"0c60c80f961f0e71f3a9b524af6012062fe037a6","base64":"DGDID5YfDnHzqbUkr2ASBi/gN6Y=","length":20,"iterations":1,"work_units":1}},{"input":{"password":"passwd","salt":"salt","algorithm":"sha256","iterations":1,"length":64},"output":{"algorithm":"sha256","hex":"55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783","base64":"VawEblbjCJ/sFpHCJUS2BflBhSFt3gRl5oudV8INrLxJypzM8Xm2RZkWZLOdd+8xfHG4RbHjC9UJESBB06GXgw==","length":64,"iterations":1,"work_units":2}}],"execute_url":"/v1/tools/pbkdf2-compute/versions/1.0.0/execute"}