The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Hash bytes with SHA-256digest = hashlib.sha256(data).digest()View examples
Render a hexadecimal digesttext = hashlib.sha256(data).hexdigest()View examples
Hash data incrementallyhasher.update(chunk)View examples
Hash an open binary filewith path.open('rb') as file: digest = hashlib.file_digest(file, 'sha256')View examples
Branch a partial hashbranch = hasher.copy()View examples
Construct an algorithm by namehasher = hashlib.new('sha256', data)View examples
Inspect portable algorithmsportable = hashlib.algorithms_guaranteedView examples
Build an HMAC incrementallymac = hmac.new(key, message, digestmod=hashlib.sha256)View examples
Calculate an HMAC in one calltag = hmac.digest(key, message, 'sha256')View examples
Compare authenticators safelyvalid = hmac.compare_digest(received_tag, expected_tag)View examples
Generate random secret byteskey = secrets.token_bytes(32)View examples
Generate a hexadecimal tokentoken = secrets.token_hex(32)View examples
Generate a URL-safe tokentoken = secrets.token_urlsafe(32)View examples
Choose securely from a sequencecharacter = secrets.choice(alphabet)View examples
Generate a bounded integerindex = secrets.randbelow(exclusive_upper_bound)View examples
Derive a PBKDF2 verifierderived = hashlib.pbkdf2_hmac('sha256', password, salt, iterations, dklen=32)View examples
Derive a scrypt verifierderived = hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1, dklen=32)View examples
Create a unique password saltsalt = secrets.token_bytes(16)View examples
Authenticate with keyed BLAKE2tag = hashlib.blake2b(message, key=key, digest_size=32).digest()View examples
Separate BLAKE2 domainsdigest = hashlib.blake2b(data, person=b'cache-v1', digest_size=16).digest()View examples

Cryptographic APIs solve different problems: a digest fingerprints bytes, a MAC authenticates bytes with a shared secret, a password KDF deliberately slows guessing, and a cryptographically secure random generator creates unpredictable tokens. Choose the primitive by threat model, encode inputs explicitly, carry algorithm and parameter metadata with stored results, and compare authenticators with compare_digest. Hashes are neither encryption nor proof of authenticity, and the random module is not suitable for secrets.

Step by step

Detailed examples

01

Hash a precisely encoded byte sequence

Hash functions consume bytes, so define the encoding and serialization before computing a digest. Updating with chunks is equivalent to hashing their concatenation and supports bounded-memory file processing. digest returns raw bytes for protocols and storage; hexdigest returns a display-friendly representation twice as long. hashlib.file_digest was added in Python 3.11 and may bypass normal file-object methods, so treat the file object's position as unknown afterward and close it through a context manager.

Verify that streaming and one-shot hashing agree
import hashlib

payload = 'café'.encode('utf-8')
one_shot = hashlib.sha256(payload)
streamed = hashlib.sha256()
streamed.update(payload[:3])
streamed.update(payload[3:])

print(one_shot.hexdigest())
print(streamed.digest() == one_shot.digest())
print(one_shot.digest_size)
Output
850f7dc43910ff890f8879c0ed26fe697c93a067ad93a7d50f466a7028a9bf4e
True
32
Back to quick reference ↑
02

Choose algorithms by purpose and interoperability requirements

SHA-256 and SHA-3 are common choices for collision-resistant content digests, while BLAKE2 offers configurable output and keyed modes. MD5 and SHA-1 have known collision weaknesses and must not protect signatures, certificates, or adversarial integrity; a usedforsecurity=False argument can identify an explicitly non-security use on restricted builds, but does not repair an algorithm. algorithms_guaranteed is portable, whereas algorithms_available depends on the linked OpenSSL provider. A plain digest detects accidental changes only when the expected digest arrives through a trusted channel.

Branch a shared prefix into two SHA-256 messages
import hashlib

prefix = hashlib.sha256(b'event:')
created = prefix.copy()
created.update(b'created')
deleted = prefix.copy()
deleted.update(b'deleted')

print(created.hexdigest()[:16])
print(deleted.hexdigest()[:16])
print(created.digest() != deleted.digest())
print('sha256' in hashlib.algorithms_guaranteed)
Output
77bcff09719f629c
346f09bf9585f92e
True
True
Back to quick reference ↑
03

Authenticate messages with a secret key

HMAC binds a message to a shared secret and detects tampering by parties without that secret. Select digestmod explicitly and authenticate an unambiguous serialization that includes every security-relevant field, protocol version, and context. Never reuse an ordinary unhashed prefix-secret construction as a substitute. Verify the received tag with hmac.compare_digest rather than ==; inputs must have the same type, and differing lengths or types can still reveal metadata. HMAC provides authenticity, not confidentiality or replay protection.

Sign a message and reject a modified one
import hashlib
import hmac

key = b'demonstration-key-not-for-production'
message = b'v1|account=42|amount=1250'
tag = hmac.new(key, message, hashlib.sha256).digest()

def verify(candidate, received):
    expected = hmac.digest(key, candidate, 'sha256')
    return hmac.compare_digest(received, expected)

print(tag.hex())
print(verify(message, tag))
print(verify(b'v1|account=42|amount=9000', tag))
Output
fc6aa259738cf41ce5349bfa8a1cdf007d6f3046e5640390f097dada8935e3e1
True
False
Back to quick reference ↑
04

Generate unpredictable tokens with explicit entropy

secrets obtains randomness from the operating system and is intended for credentials, reset links, session identifiers, and cryptographic keys. Pass nbytes explicitly because the default token entropy is intentionally subject to change, even during maintenance releases. token_hex is convenient for case-insensitive text fields; token_urlsafe uses unpadded URL-safe Base64 and is more compact. Store only a digest or MAC of bearer tokens when practical, set an expiry and purpose, and do not log secret values. The random module is designed for simulation, not attackers.

Generate tokens while displaying only stable properties
import secrets

raw = secrets.token_bytes(16)
hex_token = secrets.token_hex(16)
url_token = secrets.token_urlsafe(18)
index = secrets.randbelow(10)

print(len(raw), len(hex_token), len(url_token))
print(all(character in '0123456789abcdef' for character in hex_token))
print(0 <= index < 10)
Output
16 32 24
True
True
Back to quick reference ↑
05

Use a password KDF and version every cost parameter

Never store passwords or hash them directly with SHA-256, SHA-3, or BLAKE2. Use a dedicated password-hashing library where possible. hashlib exposes PBKDF2-HMAC and scrypt through compatible OpenSSL builds; since Python 3.12, PBKDF2-HMAC no longer has a slow pure-Python fallback. Generate a unique random salt for each password and store the KDF name, salt, cost parameters, and derived value. Tune cost on production hardware, cap attacker-controlled parameters before verification, compare with compare_digest, and upgrade successful logins when policy changes. Fixed salts and modest costs below are reproducible test vectors, not deployment policy.

Create and verify a deterministic PBKDF2 test vector
import hashlib
import hmac

password = 'correct horse battery staple'.encode('utf-8')
salt = bytes.fromhex('00112233445566778899aabbccddeeff')
iterations = 100_000
stored = hashlib.pbkdf2_hmac('sha256', password, salt, iterations, dklen=32)
candidate = hashlib.pbkdf2_hmac('sha256', password, salt, iterations, dklen=32)
wrong = hashlib.pbkdf2_hmac('sha256', b'wrong', salt, iterations, dklen=32)

print(stored.hex())
print(hmac.compare_digest(stored, candidate))
print(hmac.compare_digest(stored, wrong))
Output
2a080fdedce213934a91e8142d2eb7165be949c295612ce4b7d87be90ae208b6
True
False
Back to quick reference ↑
06

Use BLAKE2's keyed and personalized modes intentionally

BLAKE2b and BLAKE2s support explicit digest sizes, keys, salts, and personalization. Keyed mode is a native MAC construction, not merely key bytes concatenated with a message. Personalization separates application domains so identical input used for two protocols does not automatically share a digest; it is public context, not a secret. BLAKE2 salt is a fixed constructor parameter with strict maximum length and is not a password-hashing salt. General-purpose BLAKE2 remains unsuitable for password storage because it is intentionally fast.

Separate two BLAKE2 digest domains and authenticate one
from hashlib import blake2b
import hmac

payload = b'customer:42'
cache_id = blake2b(payload, digest_size=16, person=b'cache-v1').digest()
audit_id = blake2b(payload, digest_size=16, person=b'audit-v1').digest()
tag = blake2b(payload, key=b'32-byte-demo-key-material-value!', digest_size=16).digest()
expected = blake2b(payload, key=b'32-byte-demo-key-material-value!', digest_size=16).digest()

print(cache_id.hex())
print(audit_id.hex())
print(cache_id != audit_id)
print(hmac.compare_digest(tag, expected))
Output
cf8043a1a37b3d7a7acd583a40b416ed
46e1380c886506a951c5131976b7ba4f
True
True
Back to quick reference ↑

Local code tester

Hash and authenticate a structured message

Compare a public content digest with a keyed authenticator and verify both the original and a modified message.

Runs in your browser
Output
Press Run to load Python locally.

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Python Software Foundationhashlib — Secure hashes and message digestsdocs.python.org
  2. Python Software Foundationhmac — Keyed-Hashing for Message Authenticationdocs.python.org
  3. Python Software Foundationsecrets — Generate secure random numbers for managing secretsdocs.python.org
  4. Python Software FoundationSecurity considerationsdocs.python.org
  5. Python Software FoundationPEP 506 — Adding a Secrets Module to the Standard Librarypeps.python.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback