hashlib, secrets & uuid
hashlib provides cryptographic and fast hashes (SHA-256). secrets generates unpredictable tokens. uuid creates standard unique identifiers - pick the right tool for checksums vs session tokens vs primary keys.
Recipe
import hashlib
import secrets
digest = hashlib.sha256(b"payload").hexdigest()
token = secrets.token_urlsafe(32)When to reach for this:
- File integrity checksums -> hashlib
- Session/API tokens -> secrets
- Database primary keys -> uuid4
- Password storage -> never plain hashlib alone; use argon2/bcrypt PyPI
- HMAC message auth -> hmac module with secret key
Working Example
import hashlib
import secrets
import uuid
def sha256_hex(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def new_session_token() -> str:
return secrets.token_hex(16)
def new_record_id() -> str:
return str(uuid.uuid4())
payload = b"important"
print("sha256", sha256_hex(payload))
print("session", new_session_token())
print("uuid", new_record_id())
# compare digests in constant time
a = sha256_hex(b"x")
b = sha256_hex(b"x")
print(secrets.compare_digest(a, b))What this demonstrates:
- sha256 for content fingerprinting (not passwords)
- secrets module for CSPRNG tokens
- uuid4 random IDs for distributed systems
compare_digestprevents timing leaks on comparisons
Deep Dive
Choice Guide
| Need | Module |
|---|---|
| Random URL token | secrets.token_urlsafe |
| Stable content hash | hashlib.sha256 |
| DB uuid column | uuid.uuid4 |
| Password hash | argon2-cffi / bcrypt |
uuid versions
- uuid4 random - default IDs
- uuid7 (3.14+ time-ordered) - index-friendly where supported
Gotchas
- sha256 for passwords - too fast, no salt. Fix: dedicated password hashers.
- random module for tokens - predictable. Fix: secrets only.
- uuid1 MAC leakage - privacy concern. Fix: uuid4 for public ids.
- Hex digest case - compare consistently; use compare_digest.
- Hashing large files - memory load. Fix: incremental
hashlib.file_digest(3.11+) or update loop.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| argon2 | Password storage | File checksum |
| ULID PyPI | Sortable ids pre-uuid7 | Stdlib-only |
| HMAC | Signed tokens | Plain digest enough |
FAQs
secrets vs os.urandom?
secrets wraps urandom with helpers; both CSPRNG for tokens.
hashlib algorithms?
sha256 common; avoid md5/sha1 for security-sensitive integrity.
uuid in URLs?
uuid4 fine; use secrets token if opaque capability URL needed.
file_digest?
3.11+ reads file in chunks: hashlib.file_digest(open(path,"rb"), "sha256").
salt passwords?
Use library - never manual salt + single hash iteration.
token_hex vs urlsafe?
urlsafe shorter for same entropy in URL paths; hex simpler for logs.
UUID DB type?
Native UUID column in Postgres; store as str or uuid type per ORM.
HMAC example?
hmac.new(key, msg, hashlib.sha256).hexdigest() for signed webhooks.
entropy length?
16 bytes (128 bit) minimum for session tokens in many threat models.
uuid7 benefit?
Time-ordered reduces DB index fragmentation vs random uuid4.
Related
- json & Serialization - tokens in JSON
- subprocess - verify checksums of artifacts
- Standard Library Overview - map
- Password & Credential Handling - auth patterns
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.