751 words
4 minutes
Python hashlib Module - Complete Tutorial

# hashlib Module#

What is hashlib?#

hashlib is Python’s built-in module for hashing. It’s included with Python (no installation needed) and provides interfaces to many secure hash algorithms like SHA256, MD5, and more.


Why Use It in Cybersecurity?#

  • Hash passwords securely
  • Verify file integrity
  • Create fingerprints of data
  • Compare data without storing originals
  • Generate checksums
  • Analyze password hash formats
  • Test for weak hash algorithms

Installation#

Terminal window
# No installation needed - hashlib is built into Python!
# Just import it:
import hashlib

Basic Usage#

import hashlib
data = "Hello World"
# Create SHA256 hash
hash_obj = hashlib.sha256(data.encode())
hash_value = hash_obj.hexdigest()
print(f"Data: {data}")
print(f"SHA256: {hash_value}")

Output:

Data: Hello World
SHA256: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146

MD5 Hash (Weak - for analysis only)#

import hashlib
password = "admin123"
md5_hash = hashlib.md5(password.encode()).hexdigest()
print(f"Password: {password}")
print(f"MD5: {md5_hash}")

SHA1 Hash#

import hashlib
data = "Secret Message"
sha1_hash = hashlib.sha1(data.encode()).hexdigest()
print(f"Data: {data}")
print(f"SHA1: {sha1_hash}")

Hash Multiple Times (Slow Hashing)#

import hashlib
def slow_hash(password, salt, iterations=10000):
data = password.encode() + salt
for _ in range(iterations):
data = hashlib.sha256(data).digest()
return data.hex()
# Hash with salt
salt = b'random_salt_value'
hashed = slow_hash("mypassword", salt)
print(f"Salted Hash: {hashed}")

Real-World Cybersecurity Uses#

1. Password Hashing (with Salt)#

import hashlib
import secrets
def hash_password(password):
# Generate random salt
salt = secrets.token_hex(16).encode()
# Combine password + salt
data = password.encode() + salt
# Hash
hashed = hashlib.sha256(data).hexdigest()
# Store: salt + hash
return salt.hex() + ":" + hashed
def check_password(password, stored):
# Split into salt and hash
salt_hex, stored_hash = stored.split(":", 1)
salt = salt_hex.encode()
# Hash input with same salt
data = password.encode() + salt
computed_hash = hashlib.sha256(data).hexdigest()
# Compare
return computed_hash == stored_hash
# Example usage
stored = hash_password("user123")
print(f"Stored: {stored}")
print("Valid login:", check_password("user123", stored)) # True
print("Invalid login:", check_password("wrong", stored)) # False

2. File Integrity Check (Malware Detection)#

import hashlib
def get_file_hash(filepath):
"""Calculate SHA256 hash of a file"""
sha256 = hashlib.sha256()
with open(filepath, 'rb') as f:
# Read file in chunks
while chunk := f.read(4096):
sha256.update(chunk)
return sha256.hexdigest()
# Check if file has been modified
original_hash = "abc123def456..."
current_hash = get_file_hash("malware.exe")
if current_hash == original_hash:
print("✅ File unchanged")
else:
print("⚠️ File modified! Possible malware!")
# Compare two files
hash1 = get_file_hash("file1.txt")
hash2 = get_file_hash("file2.txt")
if hash1 == hash2:
print("Files are identical")
else:
print("Files are different")

3. Identify Password Hash Format#

import hashlib
import re
def identify_hash_type(hash_value):
hash_value = hash_value.lower()
# MD5 (32 hex chars)
if re.match(r'^[a-f0-9]{32}$', hash_value):
return "MD5"
# SHA1 (40 hex chars)
if re.match(r'^[a-f0-9]{40}$', hash_value):
return "SHA1"
# SHA256 (64 hex chars)
if re.match(r'^[a-f0-9]{64}$', hash_value):
return "SHA256"
# SHA512 (128 hex chars)
if re.match(r'^[a-f0-9]{128}$', hash_value):
return "SHA512"
return "Unknown"
# Test
print(identify_hash_type("5f4dcc3b5aa765d61d8327deb882cf99")) # MD5
print(identify_hash_type("a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146")) # SHA256

4. Rainbow Table Attack (Demonstration)#

import hashlib
# Create simple rainbow table
rainbow_table = {}
# Common passwords (in real attacks, this has millions)
common_passwords = [
"password", "123456", "admin", "root",
"welcome", "qwerty", "letmein", "12345678"
]
# Pre-compute hashes
for password in common_passwords:
hash_value = hashlib.md5(password.encode()).hexdigest()
rainbow_table[hash_value] = password
print("Rainbow table created with", len(rainbow_table), "entries")
# Look up hash
target_hash = "5f4dcc3b5aa765d61d8327deb882cf99"
if target_hash in rainbow_table:
print(f"✅ Password found: {rainbow_table[target_hash]}")
else:
print("❌ Password not in table")
# This is why salts are important!

5. Generate Secure API Keys#

import hashlib
import secrets
import time
def generate_api_key():
# Get random bytes + timestamp
random_data = secrets.token_bytes(32)
timestamp = str(time.time()).encode()
# Combine and hash
data = random_data + timestamp
hash_value = hashlib.sha256(data).hexdigest()
# Format: add separators
return '-'.join([hash_value[i:i+8] for i in range(0, len(hash_value), 8)])
# Generate multiple keys
for i in range(3):
print(f"API Key {i+1}: {generate_api_key()}")

6. Verify Download Integrity#

import hashlib
def verify_download(filename, expected_hash):
"""Verify if downloaded file matches expected hash"""
sha256 = hashlib.sha256()
with open(filename, 'rb') as f:
while chunk := f.read(8192):
sha256.update(chunk)
computed_hash = sha256.hexdigest()
print(f"Expected: {expected_hash}")
print(f"Computed: {computed_hash}")
if computed_hash == expected_hash:
print("✅ Download verified!")
return True
else:
print("❌ Download corrupted or tampered!")
return False
# Usage
expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
status = verify_download("downloaded_file.iso", expected)

⚠️ Ethical Note#

  • Never store passwords in plain text
  • Always use salt when hashing passwords
  • Avoid MD5 and SHA1 for security (use SHA256 or better)
  • Don’t implement your own crypto - use proven libraries
  • Rainbow tables demonstrate why salts are mandatory

![Image: Hash function diagram placeholder]


Summary Table#

AlgorithmLengthSecurityUse Case
md532 charsWeakLegacy verification
sha140 charsWeakLegacy verification
sha25664 charsStrongModern security
sha512128 charsVery strongHigh-security needs

Quick Reference#

import hashlib
# Hash string
hashlib.sha256(data.encode()).hexdigest()
# Hash file (in chunks)
sha256 = hashlib.sha256()
sha256.update(chunk)
# Available algorithms
print(hashlib.algorithms_available) # See all available
print(hashlib.algorithms_guaranteed) # Always available
# Create hash object
h = hashlib.sha256()
h.update(b"data")
h.digest() # Binary
h.hexdigest() # Hex string

Security Tips#

  1. Always salt passwords to prevent rainbow table attacks
  2. Use slow hashing (hash many times) to slow down brute force
  3. Avoid MD5/SHA1 - they’re broken
  4. Prefer SHA256 for new applications
  5. Keep salt random and unique for each user

Practice: Try creating your own password manager with hashing! Remember: never store plain text passwords!