{"id":7492,"library":"pbkdf2","title":"PBKDF2 (PKCS#5 v2.0 PBKDF2 Module)","description":"The `pbkdf2` library provides a Python implementation of the Password-Based Key Derivation Function 2 (PBKDF2), as specified in RSA PKCS#5 v2.0. It is designed to derive cryptographic keys from a password and a salt, leveraging iterative hashing to increase the computational cost for brute-force attacks. The library's last release was in June 2011, and while functional, modern Python applications are generally advised to use the built-in `hashlib.pbkdf2_hmac` function, which offers better performance and active maintenance.","status":"abandoned","version":"1.3","language":"python","source_language":"en","source_url":"https://github.com/dlitz/python-pbkdf2","tags":["security","cryptography","password","hashing","pbkdf2","key-derivation"],"install":[{"cmd":"pip install pbkdf2","lang":"bash","label":"Install stable release"}],"dependencies":[],"imports":[{"symbol":"PBKDF2","correct":"from pbkdf2 import PBKDF2"},{"note":"A utility function for simpler password hashing, wraps PBKDF2.","symbol":"crypt","correct":"from pbkdf2 import crypt"}],"quickstart":{"code":"import os\nfrom pbkdf2 import PBKDF2\n\npassword = b\"mysecretpassword\"\nsalt = os.urandom(16) # Always use a unique, random salt\niterations = 100000 # Choose a high iteration count for security\ndklen = 32 # Desired key length in bytes\n\n# Derive a key using the PBKDF2 class\nderived_key = PBKDF2(password, salt, iterations).read(dklen)\n\nprint(f\"Salt: {salt.hex()}\")\nprint(f\"Derived Key: {derived_key.hex()}\")\n\n# Or use the simpler 'crypt' function (defaults to HMAC-SHA1 and specific format)\n# NOTE: 'crypt' often uses a lower default iteration count and HMAC-SHA1, consider explicit PBKDF2 for modern security standards.\npwhash = PBKDF2.crypt(password.decode(), salt.decode(), iterations)\nprint(f\"Password Hash (using .crypt): {pwhash}\")","lang":"python","description":"This quickstart demonstrates deriving a key using the `PBKDF2` class with a randomly generated salt and a high iteration count. It also shows the `crypt` helper function, though explicit use of `PBKDF2` is often preferred for control over the hashing algorithm and iterations."},"warnings":[{"fix":"Migrate to `hashlib.pbkdf2_hmac` for new projects and consider for existing ones. Example: `from hashlib import pbkdf2_hmac; key = pbkdf2_hmac('sha256', password_bytes, salt_bytes, iterations, dklen=32)`.","message":"This `pbkdf2` package has not been updated since 2011. Python's standard library `hashlib` module provides `hashlib.pbkdf2_hmac`, which is the recommended, actively maintained, and often more performant way to perform PBKDF2.","severity":"deprecated","affected_versions":"1.0 - 1.3"},{"fix":"Always explicitly specify a strong hash function like SHA-256 or SHA-512 when using PBKDF2, especially if migrating to `hashlib.pbkdf2_hmac`. The `pbkdf2` library (dlitz/python-pbkdf2) does not offer a direct way to change the HMAC algorithm for the `PBKDF2` class itself; this is another reason to prefer `hashlib.pbkdf2_hmac`.","message":"The `pbkdf2` library's default hashing algorithm for `PBKDF2` can be HMAC-SHA1 if not explicitly specified, which is less secure than SHA-256 or SHA-512 for password hashing in modern applications.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use a high iteration count, typically hundreds of thousands, and increase it over time as computing power grows. `iterations = 600000` or higher is a good starting point for 2026.","message":"Using a low iteration count (rounds) severely weakens the security against brute-force attacks. Older examples or default values might be dangerously low for current computing power.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Generate a unique salt for each password using `os.urandom(16)` (or more bytes) and store it securely with the derived key/hash. Never use a fixed or easily guessable salt.","message":"Failing to use a unique, cryptographically secure random salt for each password or not storing the salt alongside the hash is a critical security vulnerability. Reusing salts or using predictable salts enables rainbow table attacks.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'2':22 '2011':65 '5':3,29 'activ':88 'advis':74 'applic':71 'attack':56 'base':18 'better':85 'brute':54 'brute-forc':53 'built':79 'built-in':78 'comput':50 'cost':51 'cryptograph':36 'cryptographi':91 'deriv':20,35,97 'design':33 'forc':55 'function':21,68,82 'general':73 'hash':46,93 'hashlib.pbkdf2_hmac':81 'implement':13 'increas':48 'iter':45 'june':64 'key':19,37,96 'key-deriv':95 'last':60 'leverag':44 'librari':9,58 'mainten':89 'modern':69 'modul':6 'offer':84 'password':17,40,92 'password-bas':16 'pbkdf2':1,5,8,23,94 'perform':86 'pkcs':2,28 'provid':10 'python':12,70 'releas':61 'rsa':27 'salt':43 'secur':90 'specifi':25 'use':76 'v2.0':4,30","created_at":"2026-04-16T14:00:37.901450+00:00","updated_at":"2026-04-16T14:00:37.901450+00:00","problems":[{"fix":"Ensure all PBKDF2 parameters (password, salt, iterations, desired key length, and HMAC hash algorithm) are identical across implementations. Convert passwords and salts to byte strings consistently (e.g., `password.encode('utf-8')`). Explicitly set the hash algorithm, e.g., 'sha256'. Confirm the derived key length (`dklen`) is the same. Python's `hashlib.pbkdf2_hmac` is often easier to synchronize.","cause":"Inconsistent parameters (hash algorithm, salt encoding, iteration count, key length) or byte-string handling between implementations. Forgetting that `pbkdf2` often defaults to SHA-1 or different byte representations.","error":"PBKDF2 output differs across platforms/languages (e.g., Python vs C#)"},{"fix":"Verify the correct installation with `pip show pbkdf2` and check the import: `from pbkdf2 import PBKDF2` or `from pbkdf2 import crypt`. If `pbkdf2.py` is directly in the path, it might be picked up instead of the installed package. Consider using the fully qualified name `pbkdf2.PBKDF2` or `pbkdf2.crypt` if `from pbkdf2 import ...` causes issues due to other modules named `pbkdf2`.","cause":"Incorrect import statement or a different `pbkdf2` package being installed/imported. Some systems might have other `pbkdf2` related modules or older versions where `PBKDF2` might be nested.","error":"AttributeError: 'module' object has no attribute 'PBKDF2' or 'crypt'"},{"fix":"Encode the password and salt to byte strings before passing them to `PBKDF2` or `crypt`. For example: `password.encode('utf-8')` and `salt.encode('utf-8')` (if salt is a string) or `os.urandom(16)` for binary salt.","cause":"The `pbkdf2` functions expect byte strings for `password` and `salt`, but a Python 3 `str` (unicode) object was provided. This is a common Python 2 to 3 migration issue.","error":"TypeError: ('expected bytes, got str',)"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.3","cli_name":"","cli_version":null,"type":"library","homepage":"http://www.dlitz.net/software/python-pbkdf2/","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/pbkdf2/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}