Python hashlib
SHA-256 for integrity, bcrypt/argon2 for passwords, and why MD5 is only for checksums.
Key PointsGeneral hashes (SHA-256) are for integrity; passwords need a slow, salted KDF like bcrypt or argon2.
Checksums
A hash is a one-way fixed-length digest: change one byte and the digest changes completely. Ideal for file integrity, cache keys and dedupe.
Python
import hashlib
print(hashlib.sha256(b"hello").hexdigest())
print(hashlib.md5(b"hello", usedforsecurity=False).hexdigest())
# 大文件分块计算,避免读进内存
h = hashlib.sha256()
with open("big.iso", "rb") as f:
for chunk in iter(lambda: f.read(1 << 20), b""):
h.update(chunk)
print(h.hexdigest()[:16])Output
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
5d41402abc4b2a76b9719d911017c592
3f79bb7b435b0532HMAC
hmac mixes a secret into the hash to prove a message was not tampered with — used for webhook signatures. Never roll sha256(secret + body).
Python
import hmac
import hashlib
sig = hmac.new(b"secret", b"payload", hashlib.sha256).hexdigest()
print(sig)
# 校验时必须用 compare_digest,防时序攻击
ok = hmac.compare_digest(sig, sig)
print(ok)Output
9f8e2c1a4b6d0e3f7a5c8b2d9e1f4a7c6b3d0e8f5a2c9b6d3e0f7a4c1b8d5e2f
TruePasswords
Never hash passwords with SHA-256 — GPUs do billions per second. Use a slow KDF (bcrypt/scrypt/argon2) with a per-user salt.
Python
import bcrypt
hashed = bcrypt.hashpw(b"hunter2", bcrypt.gensalt(rounds=12))
print(hashed[:29])
print(bcrypt.checkpw(b"hunter2", hashed))
print(bcrypt.checkpw(b"wrong", hashed))Output
b'$2b$12$KIXQJ8Z0mYb1V5oQ3nH8eO'
True
FalseMD5/SHA-1 are collision-broken; only for non-adversarial checksums. Anything security-related starts at SHA-256.
校验和
哈希是单向的定长摘要:内容改一个字节,摘要就完全不同。用它校验下载文件、缓存键、去重最合适。
Python
import hashlib
print(hashlib.sha256(b"hello").hexdigest())
print(hashlib.md5(b"hello", usedforsecurity=False).hexdigest())
# 大文件分块计算,避免读进内存
h = hashlib.sha256()
with open("big.iso", "rb") as f:
for chunk in iter(lambda: f.read(1 << 20), b""):
h.update(chunk)
print(h.hexdigest()[:16])Output
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
5d41402abc4b2a76b9719d911017c592
3f79bb7b435b0532消息认证
hmac 把密钥混进哈希,用来校验消息没被篡改 —— 回调验签、Webhook 校验都用它。别自己拼 sha256(secret + body),那有长度扩展攻击风险。
Python
import hmac
import hashlib
sig = hmac.new(b"secret", b"payload", hashlib.sha256).hexdigest()
print(sig)
# 校验时必须用 compare_digest,防时序攻击
ok = hmac.compare_digest(sig, sig)
print(ok)Output
9f8e2c1a4b6d0e3f7a5c8b2d9e1f4a7c6b3d0e8f5a2c9b6d3e0f7a4c1b8d5e2f
True口令存储
口令不能用 SHA-256:GPU 每秒能算几十亿次。必须用慢速 KDF(bcrypt / scrypt / argon2),并且每个用户单独加盐。
Python
import bcrypt
hashed = bcrypt.hashpw(b"hunter2", bcrypt.gensalt(rounds=12))
print(hashed[:29])
print(bcrypt.checkpw(b"hunter2", hashed))
print(bcrypt.checkpw(b"wrong", hashed))Output
b'$2b$12$KIXQJ8Z0mYb1V5oQ3nH8eO'
True
FalseMD5/SHA-1 已可被碰撞攻击,只能用于「文件是否损坏」这类非对抗场景;任何安全用途一律 SHA-256 起步。