0% found this document useful (0 votes)
1 views5 pages

Is Lab 7 Python Passwords and Hash

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views5 pages

Is Lab 7 Python Passwords and Hash

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Rachna College of Engineering and Technology, Gujranwala

(A Constituent College of UET, Lahore)


Department of Computer Science
Lab 7 [Python Passwords, Salts and File Hash] [CLO 2]
Learning Objectives
By the end of this lab, students will be able to:
• Use Python's hashlib library to generate hash values using multiple algorithms
• Explain the difference between binary (.digest) and hexadecimal (.hexdigest) output formats
• Understand the role of salting in password security and implement it correctly
• Build a complete password registration and login system using PBKDF2-HMAC
• Generate and verify file integrity hashes using chunk-based reading
• Demonstrate the avalanche effect by observing how a single-character change affects the hash
Background / Theory
Cryptographic Hash Functions
A cryptographic hash function takes an input of any size and produces a fixed-size output called a digest.
Well-designed hash functions have three essential properties: they are deterministic (same input always
gives the same output), one-way (it is computationally infeasible to reverse the hash back to the input), and
collision-resistant (it is infeasible to find two different inputs that produce the same digest).
Algorithm Digest Size Status Notes
Collisions found; never use for
MD5 128 bits (16 B) Broken
security
Deprecated by NIST; avoid for new
SHA-1 160 bits (20 B) Deprecated
systems
Recommended general-purpose
SHA-256 256 bits (32 B) Secure
algorithm
SHA-512 512 bits (64 B) Secure Stronger; slower on 32-bit systems
BLAKE2s 256 bits (32 B) Secure Faster than SHA-256 in software
Salting and Why It Matters
Without salting, two users with the same password produce identical hashes. An attacker who obtains the
hash database can break millions of accounts simultaneously using precomputed rainbow tables. A salt is a
random value generated fresh for each password and stored alongside the hash. It ensures every stored hash
is unique, even for identical passwords, making rainbow table attacks infeasible.
PBKDF2-HMAC (Password-Based Key Derivation Function 2)
PBKDF2 deliberately slows down the hashing process by repeating the HMAC-SHA256 hash function
thousands of times (100,000 in this lab). This makes brute-force attacks computationally expensive even if
the attacker obtains the full hash database. The output is a derived key that can be safely stored in place of
the original password.
File Integrity Hashing
Hashing is not limited to passwords. It is widely used to verify that a file has not been modified or corrupted
in transit. A hash of the original file is computed and recorded. Later, the file is re-hashed and the two values
are compared — any change to even a single byte produces a completely different hash, making tampering
detectable.
Lab Outline
• Task 1 — Basic hashing with hashlib: single-pass and iterative update modes
• Task 1a — Multi-algorithm hash comparison script (MD5, SHA-256, SHA-512, BLAKE2s)
1
CSC-201L Information Security (Lab) Semester Spring 2026
• Task 2 — Salted password hashing and authentication using PBKDF2-HMAC
• Task 2b — Password registration and login system
• Task 3 — File integrity checking using chunk-based SHA-256 hashing
• Task 3c — Full tamper detection demonstration
Task 1: Basic Hashing with hashlib
Python's built-in hashlib library provides a uniform interface to many modern hashing algorithms. No
additional installation is required — it ships with every Python 3 distribution.

Checking Available Algorithms


To see all algorithms supported by your system's OpenSSL installation, run:
import hashlib
print(hashlib.algorithms_available)

Single-Pass Hashing
The simplest way to hash a string is to pass the encoded bytes directly to the algorithm constructor and
call .hexdigest():
import hashlib

message = "Hello World!"


hashed = hashlib.sha256([Link]()).hexdigest()
print("SHA-256 Hash:", hashed)
The .encode() call converts the string to bytes, which hashlib requires. .hexdigest() returns the hash as a
human-readable hexadecimal string.

Iterative Update Mode


For large data or streaming input, create a hash object and feed it data in pieces using .update(). The final
digest is identical to a single-pass hash of all the data concatenated:
import hashlib

hash_object = hashlib.sha256() # Create hash object


hash_object.update(b"Hello, ") # Feed first chunk
hash_object.update(b"World!") # Feed second chunk
print(hash_object.hexdigest()) # Same result as hashing "Hello, World!" at once

Digest Output Formats


hash_object = hashlib.sha256(b"Hello")

print("Binary digest:", hash_object.digest()) # Raw bytes

print("Hex digest: ", hash_object.hexdigest()) # Hexadecimal string

Method Returns Use Case

.update(data) — Feed additional bytes into the hash object

.digest() bytes Binary output; used when storing in binary databases

.hexdigest() str Hex string; used for display, comparison, and text storage

Task 1a — Multi-Algorithm Hash Comparison Script

2
CSC-201L Information Security (Lab) Semester Spring 2026
Write a Python script that takes a string as input and prints its hash under MD5, SHA-256, SHA-512, and
BLAKE2s. Run it with the same input string and observe that:
• All four algorithms always produce the same output for the same input (deterministic)
• Changing even one character of the input completely changes the output (avalanche effect)
• MD5 and SHA-256 produce shorter digests than SHA-512; BLAKE2s defaults to 32 bytes
Expected output format:
Input : Hello World!
MD5 : ed076287532e86365e841e92bfc50d8c
SHA-256 : 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069
SHA-512 : 861844d6704e8d158f... (128 hex characters)
BLAKE2s : 508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982
Task 2: Salted Password Hashing and Authentication

PBKDF2-HMAC Syntax Reference


hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)

Parameter Description
hash_name Inner hash algorithm, e.g. 'sha256'
password Password as bytes — use .encode() to convert a string
salt Random bytes — use [Link](16) to generate a fresh 16-byte salt
iterations Number of hash rounds — use 100000 as a minimum for security
dklen Derived key length in bytes; defaults to the algorithm's output length

The following fragment illustrates the basic salted hashing pattern:


import hashlib, os

password = "securepassword"
salt = [Link](16) # 16 random bytes, unique each time

hashed_password = hashlib.pbkdf2_hmac(
'sha256',
[Link](),
salt,
100000
)

stored = [Link]() + ":" + hashed_password.hex()


print("Stored string:", stored)
The stored string concatenates the salt and hash separated by a colon. Both are required for verification. The
salt is not secret and is always stored alongside the hash.
Task 2b — Password Registration and Login System
Write a Python script implementing two functions and a simple interactive menu.
Function 1 — hash_password(password) (simulates user registration)
This function should perform the following steps:
i. Generate a 16-byte random salt using [Link](16)
ii. Hash the password using PBKDF2-HMAC with SHA-256 and 100,000 iterations
iii. Return the stored string in the format {salt_hex}:{hash_hex}

3
CSC-201L Information Security (Lab) Semester Spring 2026
import hashlib, os

def hash_password(password):
salt = [Link](16)
hashed = hashlib.pbkdf2_hmac('sha256', [Link](), salt, 100000)
return f"{[Link]()}:{[Link]()}"
Function 2 — verify_password(password, stored_hash) (simulates login)
This function should perform the following steps:
i. Split stored_hash on the colon : to extract the salt and the expected hash
ii. Convert the salt from hex back to bytes using [Link]()
iii. Re-hash the entered password using the extracted salt and the same PBKDF2 parameters
iv. Compare the newly computed hash with the stored hash and return True or False
def verify_password(password, stored_hash):
salt_hex, hash_hex = stored_hash.split(":")
salt = [Link](salt_hex)
hashed = hashlib.pbkdf2_hmac('sha256', [Link](), salt, 100000)
return [Link]() == hash_hex
Main Program Flow
Your script should present a menu that allows the user to register a password and then attempt to log in. The
program should clearly indicate whether the login succeeded or failed.
=== Password Manager ===
1. Register password
2. Verify password
3. Exit

Enter choice: 1
Enter password: mypassword
Stored hash: a3f1...8c2:9d44...ff1

Enter choice: 2
Enter password: mypassword
Result: Access granted.

Enter choice: 2
Enter password: wrongpassword
Result: Access denied.

Note: Run hash_password("hello") twice and compare the two stored strings. Although the
password is identical, the two hashes will differ because a fresh random salt is generated each time.
This is the core benefit of salting.
Task 3: File Hashing and Integrity Verification
Hashing is not limited to passwords. It is widely used to verify that a file has not been modified or corrupted
in transit. A hash of the original file is computed and stored; later, the file is re-hashed and the two values
are compared. Any change to even a single byte produces a completely different hash.
Why Chunk-Based Reading?
Loading an entire file into memory before hashing is impractical for large files such as videos, disk images,
or database dumps. Reading the file in fixed-size chunks (4 KB is standard) allows arbitrarily large files to
be hashed using constant memory.
import hashlib

4
CSC-201L Information Security (Lab) Semester Spring 2026
def hash_file(filename):
hash_obj = hashlib.sha256()

with open(filename, "rb") as file:


while chunk := [Link](4096): # Read 4 KB at a time (walrus operator)
hash_obj.update(chunk)

return hash_obj.hexdigest()

file_path = input("Enter the file path: ")


file_hash = hash_file(file_path)
print(f"SHA-256 Hash: {file_hash}")
The := operator (walrus operator, Python 3.8+) assigns the result of [Link](4096) to chunk and
evaluates to that value simultaneously, stopping the loop when read() returns an empty bytes object.
Task 3c — Full Integrity Verification Script
Extend the code above into a complete integrity checking program that performs the following steps:
i. Prompt the user for a file path and compute its initial SHA-256 hash
ii. Store the hash as the trusted baseline
iii. Instruct the user to open and modify the file (add or delete any character, then save)
iv. Recompute the hash of the modified file
v. Compare the new hash with the baseline and print whether the file is intact or tampered
File: [Link]
Original hash : 3b4c9a...f221
--- Modify the file now, then press Enter ---
New hash : 9f17de...4a30
Integrity check: FAILED — file has been modified.
Test Procedure
i. Create a plain text file with any content
ii. Run the script and record the original hash
iii. Open the file in a text editor, add a single space anywhere, and save
iv. Press Enter in the script to re-hash and verify — confirm the hash has changed
<<Good Luck>>

5
CSC-201L Information Security (Lab) Semester Spring 2026

You might also like