{
    "slug": "key_derivation_functions",
    "term": "Key Derivation Functions",
    "category": "cryptography",
    "difficulty": "advanced",
    "short": "KDFs (PBKDF2, bcrypt, scrypt, Argon2) derive a cryptographic key from a password by being intentionally slow — making brute-force attacks computationally infeasible.",
    "long": "Passwords must not be stored directly — a KDF transforms a password into a hash that cannot be reversed, and is deliberately slow to compute. bcrypt: adaptive cost factor, max 72 chars, PHP's password_hash() default. scrypt: memory-hard (GPU/ASIC resistant) — good for application-level KDFs. Argon2 (Argon2id recommended): winner of Password Hashing Competition, configurable time+memory+parallelism — PHP password_hash() with PASSWORD_ARGON2ID. PBKDF2: NIST-approved, widely supported, less memory-hard than Argon2/scrypt. Never use MD5/SHA (fast — trivially brute-forced).",
    "aliases": [
        "PBKDF2",
        "bcrypt",
        "scrypt",
        "Argon2",
        "password hashing",
        "KDF"
    ],
    "tags": [
        "cryptography",
        "security",
        "php",
        "passwords"
    ],
    "misconception": "SHA-256 is a strong password hash — SHA-256 is a fast hash designed for integrity checking; it can hash billions of passwords per second on a GPU — use Argon2id or bcrypt instead.",
    "why_it_matters": "A leaked database with SHA-256 hashed passwords is cracked within hours with a GPU; the same database with Argon2id hashes would take centuries — the algorithm choice is the critical factor.",
    "common_mistakes": [
        "MD5 or SHA-1 for passwords — deprecated and trivially cracked; any data breach is catastrophic.",
        "bcrypt with passwords > 72 characters — bcrypt silently truncates; use Argon2id for long passwords.",
        "Low cost/iteration count — makes hashing fast and brute force feasible; use the highest cost your server tolerates.",
        "Not using PHP's password_verify() — manual comparison with == is vulnerable to timing attacks; password_verify() uses constant-time comparison."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "bcrypt",
        "argon2",
        "password_hash",
        "salted_hash",
        "weak_cryptography"
    ],
    "prerequisites": [
        "symmetric_encryption",
        "entropy",
        "hash_functions_deep"
    ],
    "refs": [
        "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"
    ],
    "bad_code": "// MD5 password hash — trivially cracked:\n$hash = md5($password);          // Cracked in seconds with GPU\n$hash = sha256($password);       // Fast — millions/sec on GPU\n$hash = md5(md5($password));     // Still fast — do not use\n\n// Manual comparison — timing attack:\nif ($storedHash === md5($password)) { /* login */ }",
    "good_code": "// Argon2id — slow, memory-hard, PHP native:\n$hash = password_hash($password, PASSWORD_ARGON2ID, [\n    'memory_cost' => 65536,  // 64 MB\n    'time_cost'   => 4,      // 4 iterations\n    'threads'     => 2,\n]);\n\n// Verify with constant-time comparison:\nif (password_verify($password, $hash)) {\n    // Login — rehash if needs_rehash():\n    if (password_needs_rehash($hash, PASSWORD_ARGON2ID)) {\n        $newHash = password_hash($password, PASSWORD_ARGON2ID);\n        updateStoredHash($userId, $newHash);\n    }\n}",
    "quick_fix": "Use Argon2id for passwords (password_hash()), PBKDF2 for key derivation from passphrases (hash_pbkdf2()), and HKDF for expanding cryptographic keys — never use a plain hash as a key derivation function",
    "severity": "critical",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/key_derivation_functions",
        "html_url": "https://codeclaritylab.com/glossary/key_derivation_functions",
        "json_url": "https://codeclaritylab.com/glossary/key_derivation_functions.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Key Derivation Functions](https://codeclaritylab.com/glossary/key_derivation_functions) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/key_derivation_functions"
            }
        }
    }
}