Salted SHA-256 and SHA-512 Hashes in Python Hashlib
Python's hashlib module provides robust support for
generating salted SHA-256 and SHA-512 hashes through native
cryptographic primitives and dedicated key derivation functions. While
developers can manually combine a salt with standard sha256
and sha512 algorithms, hashlib specifically
incorporates PBKDF2-HMAC and scrypt to
securely implement salted hashing. This article outlines the specific
algorithms supported by hashlib for generating salted SHA
hashes, explaining how each functions and when to use them.
1. PBKDF2 with HMAC-SHA-256 and HMAC-SHA-512
For password hashing and secure credential storage,
hashlib.pbkdf2_hmac is the primary standardized algorithm
in Python's standard library that natively uses SHA-256 and SHA-512 with
salts.
PBKDF2 (Password-Based Key Derivation Function 2) applies a pseudorandom function—in this case, HMAC using either SHA-256 or SHA-512—along with a cryptographic salt across thousands of iterations to slow down brute-force attacks.
- Supported Hash Names:
'sha256'and'sha512' - Method Signature:
hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)
import hashlib
import os
salt = os.urandom(16)
password = b"user_secure_password"
# Salted SHA-256 using PBKDF2
key_sha256 = hashlib.pbkdf2_hmac('sha256', password, salt, iterations=600000)
# Salted SHA-512 using PBKDF2
key_sha512 = hashlib.pbkdf2_hmac('sha512', password, salt, iterations=600000)2. Standard SHA-256 and SHA-512 via Manual Salting
Python's hashlib exposes raw SHA-2 family message-digest
algorithms:
hashlib.sha256()hashlib.sha512()hashlib.sha384(),hashlib.sha224(),hashlib.sha512_224(), andhashlib.sha512_256()(variants based on the same core engines)
These core primitives do not take a dedicated salt
parameter natively. Instead, salting is achieved by prepending,
appending, or mixing the salt bytes directly into the message before
digest generation.
salt = os.urandom(16)
data = b"sensitive_data"
# Salted raw SHA-256
hasher_256 = hashlib.sha256(salt + data)
salted_hash_256 = hasher_256.hexdigest()
# Salted raw SHA-512
hasher_512 = hashlib.sha512(salt + data)
salted_hash_512 = hasher_512.hexdigest()Note: Raw salted SHA-256 and SHA-512 are designed to be fast and are vulnerable to high-speed brute-force attacks when applied to passwords. They should primarily be used for data integrity verification, digital signatures, or non-password token generation.
3. HMAC Using SHA-256 and SHA-512
To protect against length-extension attacks inherent to simple
salt + message hashing, Python supports HMAC (Hash-based
Message Authentication Code). While implemented via the separate
hmac module, it relies directly on hashlib's
SHA-256 and SHA-512 algorithms. In this pattern, the salt acts as the
secret cryptographic key.
import hmac
salt = os.urandom(16)
message = b"message_to_authenticate"
# HMAC-SHA-256
hmac_sha256 = hmac.new(salt, message, hashlib.sha256).hexdigest()
# HMAC-SHA-512
hmac_sha512 = hmac.new(salt, message, hashlib.sha512).hexdigest()4. Scrypt (SHA-256 Derivative)
Python 3.8+ includes hashlib.scrypt(). While not a pure
SHA-512 algorithm, scrypt is a memory-hard key derivation function that
fundamentally uses PBKDF2 with HMAC-SHA-256 at its
base. It requires a distinct salt parameter and provides
protection against hardware-accelerated (ASIC/GPU) attacks.
# Salted scrypt key derivation (internally utilizes HMAC-SHA-256)
scrypt_hash = hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)Summary of Best Practices
- For storing passwords: Use
hashlib.pbkdf2_hmacwith'sha256'or'sha512', generating a unique 16-byte cryptographic salt viaos.urandom()for each record. - For data verification and message integrity: Use
hmac.new()usinghashlib.sha256orhashlib.sha512. - For general hashing: Avoid using raw, manually
concatenated
hashlib.sha256(salt + password)for authentication credentials.