import hashlib import itertools import time import string # Define character set: 0-9, a-z, A-Z, and special symbols CHARACTERS = string.digits + string.ascii_lowercase + string.ascii_uppercase + '#$%^&*' def generate_sha256_hash(password): """Generate SHA256 hash of a password.""" return hashlib.sha256(password.encode()).hexdigest() def read_password_database(filename): """ Read password database from a text file. Args: filename: Path to the file containing [username, hash] pairs Returns: List of [username, hash] pairs """ database = [] try: with open(filename, 'r') as f: for line in f: line = line.strip() if line and line.startswith('[') and line.endswith(']'): # Remove brackets and split by comma content = line[1:-1] parts = content.split(',', 1) # Split only on first comma if len(parts) == 2: username = parts[0].strip() password_hash = parts[1].strip() database.append([username, password_hash]) print(f"Loaded {len(database)} accounts from {filename}") return database except FileNotFoundError: print(f"Error: File '{filename}' not found.") return [] except Exception as e: print(f"Error reading file: {e}") return [] def dictionary_attack(password_database, N): """ Perform dictionary attack on password database. Args: password_database: List of [username, hash] pairs N: Length of passwords to try Returns: Dictionary mapping usernames to cracked passwords Time taken for the attack """ print(f"\n{'='*60}") print(f"Starting Dictionary Attack") print(f"Password length: {N}") print(f"Character set size: {len(CHARACTERS)}") print(f"Total possible passwords: {len(CHARACTERS)**N}") print(f"Number of accounts to crack: {len(password_database)}") print(f"{'='*60}\n") # Create a dictionary of hash -> username for faster lookup hash_to_user = {entry[1]: entry[0] for entry in password_database} cracked_passwords = {} start_time = time.time() attempts = 0 # Generate all possible passwords of length N for password_tuple in itertools.product(CHARACTERS, repeat=N): password = ''.join(password_tuple) attempts += 1 # Hash the password password_hash = generate_sha256_hash(password) # Check if this hash matches any in the database if password_hash in hash_to_user: username = hash_to_user[password_hash] cracked_passwords[username] = password print(f"[+] Cracked! {username}: {password}") # If all passwords are cracked, we can stop if len(cracked_passwords) == len(password_database): break # Progress indicator (every 10000 attempts for small N, adjust as needed) if attempts % 10000 == 0: print(f"Tried {attempts} passwords...") end_time = time.time() time_taken = end_time - start_time print(f"\n{'='*60}") print(f"Attack Complete!") print(f"Time taken: {time_taken:.4f} seconds") print(f"Total attempts: {attempts}") print(f"Passwords cracked: {len(cracked_passwords)}/{len(password_database)}") print(f"{'='*60}\n") return cracked_passwords, time_taken def main(): """Main function to run the dictionary attack demonstration.""" print("Dictionary Attack on SHA256 Password Hashes") print("=" * 60) # Get input file and password length from user filename = input("Enter password database filename: ") N = int(input("Enter password length N: ")) # Warn if N is too large if N > 4: total_passwords = len(CHARACTERS) ** N print(f"\nWarning: With N={N}, there are {total_passwords:,} possible passwords.") print("This may take a very long time!") confirm = input("Continue? (yes/no): ") if confirm.lower() != 'yes': print("Attack cancelled.") return # Read password database from file print("\nReading password database...") password_database = read_password_database(filename) if not password_database: print("No valid data found. Exiting.") return print("\nPassword Database:") for username, password_hash in password_database: print(f"[{username}, {password_hash}]") # Perform dictionary attack cracked_passwords, time_taken = dictionary_attack(password_database, N) # Display results print("\nResults:") for username, password in cracked_passwords.items(): print(f"{username}: {password}") print(f"\nTotal time: {time_taken:.4f} seconds") if __name__ == "__main__": main()