Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Zozi96/hash-forge/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through the most common Hash Forge workflows: hashing a password, verifying it, setting up multi-algorithm fallback for migration scenarios, running a one-liner hash, and detecting when a stored hash needs to be upgraded. By the end you will have a working foundation you can drop straight into a real project.
For new projects, use Argon2 as your primary algorithm. It is a memory-hard function that won the Password Hashing Competition and is the strongest option available in Hash Forge. Install it with pip install "hash-forge[argon2]".

Steps

1

Install Hash Forge

Install the base package from PyPI. No extras are needed for this quickstart — PBKDF2-SHA256 is included in the core and requires no additional dependencies.
pip install hash-forge
2

Hash your first password

Create a HashManager using from_algorithms(), hash a password, and verify it.
from hash_forge import HashManager

# Create a HashManager with PBKDF2-SHA256 as the sole algorithm
hash_manager = HashManager.from_algorithms("pbkdf2_sha256")

# Hash a password — returns a self-describing encoded string
hashed = hash_manager.hash("my_secure_password")
print(hashed)
# pbkdf2_sha256$150000$<salt>$<digest>

# Verify the password against the stored hash
is_valid = hash_manager.verify("my_secure_password", hashed)
print(is_valid)   # True

# Wrong password returns False — never raises an exception
is_valid_wrong = hash_manager.verify("wrong_password", hashed)
print(is_valid_wrong)  # False
The first algorithm passed to from_algorithms() becomes the preferred hasher — all new hashes are created with it. Additional algorithms are used only for verification, enabling seamless fallback.
3

Use multiple algorithms with fallback

Real applications often store hashes created by different algorithms across user cohorts. Pass multiple algorithm names to support both new and legacy hashes simultaneously.
from hash_forge import HashManager

# Requires: pip install "hash-forge[argon2]"
# Argon2 is preferred for new hashes; PBKDF2-SHA256 handles legacy hashes.
hash_manager = HashManager.from_algorithms("argon2", "pbkdf2_sha256")

# New hashes are created with Argon2 (first = preferred)
new_hash = hash_manager.hash("new_user_password")
print(new_hash[:50])
# $argon2id$v=19$m=65536,t=3,p=4$...

# A legacy PBKDF2 hash is still verifiable by the same manager
legacy_hash = HashManager.quick_hash("legacy_password", algorithm="pbkdf2_sha256")
is_valid = hash_manager.verify("legacy_password", legacy_hash)
print(is_valid)  # True — routed automatically to PBKDF2 hasher
Hash Forge inspects the hash prefix to route each verification call to the correct hasher. No if/elif branching is needed in your application code.
4

Quick one-liner hash

HashManager.quick_hash() hashes a value without creating a persistent HashManager instance. It is ideal for scripts, tests, or any context where you need a single hash on the fly.
from hash_forge import HashManager

# Default algorithm: PBKDF2-SHA256 (no extra required)
hashed = HashManager.quick_hash("my_password")
print(hashed[:50])

# Specify a different algorithm
# Requires: pip install "hash-forge[bcrypt]"
hashed_bcrypt = HashManager.quick_hash("my_password", algorithm="bcrypt")
print(hashed_bcrypt[:50])

# Pass algorithm-specific parameters
hashed_pbkdf2 = HashManager.quick_hash(
    "my_password",
    algorithm="pbkdf2_sha256",
    iterations=200_000,
)
print(hashed_pbkdf2[:50])
5

Check if a hash needs updating

needs_rehash() returns True when the parameters embedded in a stored hash fall below the current hasher’s configured thresholds — for example, when the iteration count was raised to meet updated security standards.
from hash_forge import HashManager
from hash_forge.hashers import PBKDF2Sha256Hasher

# Simulate a hash created under an older, lower-iteration configuration
old_hasher = PBKDF2Sha256Hasher(iterations=150_000)   # old standard
new_hasher = PBKDF2Sha256Hasher(iterations=200_000)   # new standard

old_hash = old_hasher.hash("password")
print(old_hash[:50])
# pbkdf2_sha256$150000$...

# Manager's preferred hasher uses 200 000 iterations
hash_manager = HashManager(new_hasher, old_hasher)
needs_update = hash_manager.needs_rehash(old_hash)
print(needs_update)  # True — 150 000 < 200 000

# After rehashing with the new hasher, needs_rehash returns False
new_hash = hash_manager.hash("password")
print(hash_manager.needs_rehash(new_hash))  # False
Call needs_rehash() after every successful login. If it returns True, re-hash the plaintext password with hash_manager.hash() and store the new hash. The user never notices.

Complete Example

The snippet below pulls together all five steps into a single runnable script you can copy straight into your project.
from hash_forge import HashManager
from hash_forge.hashers import PBKDF2Sha256Hasher

# --- Step 1: Basic hash and verify ---
hash_manager = HashManager.from_algorithms("pbkdf2_sha256")

hashed = hash_manager.hash("my_secure_password")
print("Hashed:      ", hashed[:60], "...")

is_valid = hash_manager.verify("my_secure_password", hashed)
print("Valid:       ", is_valid)         # True

is_valid_wrong = hash_manager.verify("wrong_password", hashed)
print("Wrong pw:    ", is_valid_wrong)   # False

# --- Step 2: Multi-algorithm fallback (requires hash-forge[argon2]) ---
# hash_manager_multi = HashManager.from_algorithms("argon2", "pbkdf2_sha256")
# new_hash = hash_manager_multi.hash("new_user_password")

# --- Step 3: Quick one-liner hash ---
quick = HashManager.quick_hash("simple_password")
print("Quick hash:  ", quick[:60], "...")

quick_pbkdf2 = HashManager.quick_hash(
    "simple_password",
    algorithm="pbkdf2_sha256",
    iterations=200_000,
)
print("Custom iter: ", quick_pbkdf2[:60], "...")

# --- Step 4: Rehash detection ---
old_hasher = PBKDF2Sha256Hasher(iterations=150_000)
new_hasher = PBKDF2Sha256Hasher(iterations=200_000)

old_hash = old_hasher.hash("password")
manager = HashManager(new_hasher, old_hasher)

print("Needs rehash:", manager.needs_rehash(old_hash))   # True
updated_hash = manager.hash("password")
print("After update:", manager.needs_rehash(updated_hash))  # False

Next Steps

HashManager Guide

Deep-dive into all HashManager methods: rotate(), inspect(), list_algorithms(), async operations, and policy-based hashing with PasswordHashPolicy.

Builder Pattern

Learn how to compose a fully configured HashManager with custom per-algorithm parameters using the fluent HashManager.builder() API.

Build docs developers (and LLMs) love