From 6a967bb8def3e0189faca97997d6ec1fd9358e4f Mon Sep 17 00:00:00 2001 From: valorisa Date: Fri, 11 Oct 2024 15:34:53 +0200 Subject: [PATCH] Password hasher with options in English language Password hasher with options in English language --- password_hasher_US.py | 147 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 password_hasher_US.py diff --git a/password_hasher_US.py b/password_hasher_US.py new file mode 100644 index 00000000..fd5ea4d5 --- /dev/null +++ b/password_hasher_US.py @@ -0,0 +1,147 @@ +import bcrypt +import os +import json + +def generate_salt(cost_factor: int = 12) -> str: + """ + Generates a random salt with a specified cost factor. + + :param cost_factor: The cost factor for bcrypt (default is 12). + :return: A random salt as a hexadecimal string. + """ + return bcrypt.gensalt(cost_factor).decode('utf-8') + +def hash_password(password: str, salt: str) -> str: + """ + Converts a password into a bcrypt hash with a salt. + + :param password: The password to hash. + :param salt: The salt to use for hashing. + :return: The bcrypt hash of the password with the salt. + """ + return bcrypt.hashpw(password.encode(), salt.encode()).decode('utf-8') + +def verify_password(hashed_password: str, password: str) -> bool: + """ + Verifies if the password matches the hash with the salt. + + :param hashed_password: The bcrypt hash of the password with the salt. + :param password: The password to verify. + :return: True if the password matches the hash, False otherwise. + """ + return bcrypt.checkpw(password.encode(), hashed_password.encode()) + +def save_to_file(salt: str, hashed_password: str, filename: str): + """ + Saves the salt and hash to a file. + + :param salt: The salt used for hashing. + :param hashed_password: The hash of the password. + :param filename: The name of the file to save the data. + """ + data = { + 'salt': salt, + 'hashed_password': hashed_password + } + with open(filename, 'w') as file: + json.dump(data, file) + +def load_from_file(filename: str): + """ + Loads the salt and hash from a file. + + :param filename: The name of the file to load the data. + :return: The salt and hash of the password. + """ + with open(filename, 'r') as file: + data = json.load(file) + return data['salt'], data['hashed_password'] + +def get_cost_factor(): + """ + Prompts the user to enter a valid cost factor. + + :return: The cost factor entered by the user. + """ + while True: + cost_factor_input = input("Enter the cost factor (default 12, typically between 4 and 31): ") + if cost_factor_input == '': + return 12 # Use the default value if the user enters nothing + try: + cost_factor = int(cost_factor_input) + if 4 <= cost_factor <= 31: + return cost_factor + else: + print("The cost factor must be between 4 and 31. Please try again.") + except ValueError: + print("Please enter a valid number.") + +def main(): + while True: + print("\nOptions:") + print("1. Enter a password and generate a hash.") + print("2. Verify the match between a hash and a password.") + print("3. Save the salt and hash to a file.") + print("4. Load the salt and hash from a file.") + print("5. Enter multiple passwords and generate hashes.") + print("6. Quit.") + + choice = input("Choose an option (1/2/3/4/5/6): ") + + if choice == '1': + password = input("Enter the password: ") + cost_factor = get_cost_factor() + salt = generate_salt(cost_factor) + hashed_password = hash_password(password, salt) + print(f"Salt: {salt}") + print(f"Password hash: {hashed_password}") + + elif choice == '2': + try: + hashed_password = input("Enter the password hash: ") + password_to_verify = input("Enter the password to verify: ") + match = verify_password(hashed_password, password_to_verify) + print(f"Does the password match the hash? {match}") + except Exception as e: + print(f"Error verifying the password: {e}") + + elif choice == '3': + try: + salt = input("Enter the salt: ") + hashed_password = input("Enter the password hash: ") + filename = input("Enter the filename to save the data: ") + save_to_file(salt, hashed_password, filename) + print(f"Data saved to {filename}") + except Exception as e: + print(f"Error saving the data: {e}") + + elif choice == '4': + try: + filename = input("Enter the filename to load the data: ") + salt, hashed_password = load_from_file(filename) + print(f"Salt: {salt}") + print(f"Password hash: {hashed_password}") + except Exception as e: + print(f"Error loading the data: {e}") + + elif choice == '5': + cost_factor = get_cost_factor() + while True: + password = input("Enter the password (or type 'quit' to stop): ") + if password.lower() == 'quit': + break + salt = generate_salt(cost_factor) + hashed_password = hash_password(password, salt) + print(f"Salt: {salt}") + print(f"Password hash: {hashed_password}") + + elif choice == '6': + print("Goodbye!") + break + + else: + print("Invalid option. Please choose a valid option.") + +if __name__ == "__main__": + main() +