How do security engineers, forensic investigators, and software distributors know if a sensitive file has been secretly modified by an attacker? They don't compare files line by line—they use cryptographic hashing.
A hash function takes any file (whether it is a 1 KB text file or a 10 GB operating system image) and generates a unique, fixed-length string of characters called a digital fingerprint or checksum.
In this guide, we will build a File Integrity Checker in Python using the built-in hashlib library and demonstrate how SHA-256 instantly detects unauthorized file modifications.
Prerequisites
You do not need to install any third-party packages for this project. Both hashlib and os come pre-installed with Python 3.x.
Step 1: Why Read Files in Chunks?
A common beginner mistake when hashing files in Python is calling file.read() all at once. If you try to hash a 4 GB video file or memory dump that way, Python will attempt to load all 4 GB into your system RAM at once, crashing your script.
Instead, we read the file in 64 KB binary chunks (65536 bytes) and feed each chunk into the SHA-256 algorithm sequentially. This keeps memory usage near zero regardless of file size.
Step 2: Writing the Integrity Checker (file_integrity.py)
Create a file named file_integrity.py and add the following implementation:
import hashlib
import os
def calculate_sha256(filepath):
"""Calculate SHA-256 hash by reading in 64KB chunks."""
sha256 = hashlib.sha256()
if not os.path.exists(filepath):
print(f"[-] Error: File '{filepath}' not found.")
return None
# Read binary mode in chunks to handle large files safely
with open(filepath, "rb") as f:
while chunk := f.read(65536):
sha256.update(chunk)
return sha256.hexdigest()
def demo_integrity():
test_file = "confidential_contract.txt"
# 1. Create a simulated official document
with open(test_file, "w") as f:
f.write("Payment terms: Transfer 5,000 USD to Contractor A.")
# 2. Record its baseline fingerprint (Golden Hash)
baseline_hash = calculate_sha256(test_file)
print(f"[*] Document created: '{test_file}'")
print(f"[*] Original Hash : {baseline_hash}\n")
# 3. Simulate an unauthorized modification (Tampering)
print("[!] Simulating unauthorized edit by an attacker...")
with open(test_file, "w") as f:
# Attacker modifies '5,000' to '9,000'
f.write("Payment terms: Transfer 9,000 USD to Contractor A.")
# 4. Re-calculate the hash
current_hash = calculate_sha256(test_file)
print(f"[*] Current Hash : {current_hash}\n")
# 5. Integrity Verification Audit
print("=" * 20 + " VERIFICATION AUDIT " + "=" * 20)
if current_hash == baseline_hash:
print("[+] VERIFIED: The file is authentic and unchanged.")
else:
print("[-] TAMPER DETECTED: Hashes do not match!")
print("[-] The contents have been altered or corrupted.")
if __name__ == "__main__":
demo_integrity()
Step 3: Running the Verification Audit
Run the script from your terminal:
python file_integrity.py
Terminal Output:
[*] Document created: 'confidential_contract.txt'
[*] Original Hash : 14e118e3953411eed56a2660dc2aa1d0990fca696d962b946595e6d7a94297fe
[!] Simulating unauthorized edit by an attacker...
[*] Current Hash : f3f7b6971cb53579d80f0f473baaccd0aeb5e6eba8b83fd9dc718f025b09a4a0
==================== VERIFICATION AUDIT ====================
[-] TAMPER DETECTED: Hashes do not match!
[-] The contents have been altered or corrupted.
Understanding the "Avalanche Effect"
Notice how we only altered a single digit in our text file (changing 5 to 9). Yet the output hash didn't just change by one digit—it mutated from 14e118... to f3f7b6....
In cryptography, this is known as the Avalanche Effect. A microscopic change in the input causes a drastic, unpredictable change in the output hash, making it virtually impossible for an attacker to modify a file while keeping the same SHA-256 signature.
Key Takeaway
File Integrity Monitoring (FIM) is a cornerstone of system security and digital forensics. By recording baseline SHA-256 hashes of critical system configuration files or forensic evidence, you can mathematically prove whether data has remained intact or suffered tampering.
Comments
Join the discussionNo comments yet. Be the first to comment.