def pbkdf2_hmac(mode): """ The PBKDF2 function (a special one). """ output_data = dict() if mode == "hash_file": output_data["ERROR"] = "not_supported" elif mode == "man": output_data["manual"] = globals()["pbkdf2_hmac_manual"]() else: # We are assuming here that the mode is hash_str. # Getting all the data required to implement the PBKDF2 function. input_data = get_input_data( ALL_FUNCTIONS["hashing"]["functions"]["pbkdf2_hmac"][mode]) if "ERROR" not in input_data: salt = random_string(64) output_data["text"] = input_data["text"] output_data["hash function"] = input_data["hash_function"] output_data["salt"] = salt output_data["number of iterations"] = input_data[ "number_of_iterations"] result = hashlib.pbkdf2_hmac(input_data["hash_function"], output_data["text"].encode("utf-8"), salt.encode("utf-8"), input_data["number_of_iterations"]) output_data["hash sum"] = hexlify(result).decode("utf-8") else: # Handling errors. output_data["ERROR"] = input_data["ERROR"] return output_data
def transposition(mode): """ The transposition cipher function. """ output_data = dict() # Getting all the data required to implement the # transposition cipher algorithm. input_data = get_input_data( ALL_FUNCTIONS["ciphers"]["functions"]["transposition"][mode]) if mode == "man": output_data["manual"] = transposition_manual() return output_data else: if "ERROR" not in input_data: if mode in ["encrypt", "decrypt"]: # Getting a key. key = input_parameter( f"a key (1 < integer < {len(input_data['text'])} (the length of the message))", int, range(1, len(input_data["text"]))) if "ERROR" in key: # Handling errors. output_data["ERROR"] = key["ERROR"] else: result = transposition_translate(input_data["text"], key["data"], mode) # For accuracy, the program shows a user whether # we decrypt a ciphertext or encrypt a plaintext. if mode == "encrypt": output_data["plaintext"] = input_data["text"] output_data["ciphertext"] = result else: output_data["ciphertext"] = input_data["text"] output_data["plaintext"] = result output_data["key"] = key["data"] elif mode == "attack": possible_keys = transposition_attack(input_data["text"]) if not possible_keys: output_data["ERROR"] = "keys_not_found" else: # We show the number of keys found (and those # keys too, of course). output_data[ f"possible keys ({len(possible_keys)})"] = ", ".join( possible_keys) else: # Handling errors. output_data["ERROR"] = input_data["ERROR"] return output_data
def vigenere(mode): """ The Vigenere cipher function. """ output_data = dict() # Getting all the data required to implement the # Vigenere cipher algorithm. input_data = get_input_data( ALL_FUNCTIONS["ciphers"]["functions"]["vigenere"][mode]) if mode == "man": output_data["manual"] = vigenere_manual() return output_data else: if "ERROR" not in input_data: if mode in ["encrypt", "decrypt"]: result = vigenere_translate(input_data["text"], input_data["key"], mode) # For accuracy, the program shows a user whether # we decrypt a ciphertext or encrypt a plaintext. if mode == "encrypt": output_data["plaintext"] = input_data["text"] output_data["ciphertext"] = result else: output_data["ciphertext"] = input_data["text"] output_data["plaintext"] = result output_data["key"] = input_data["key"] elif mode == "attack": global MAX_KEY_LENGTH MAX_KEY_LENGTH = input_data["max_key_length"] possible_keys = vigenere_attack(input_data["text"]) if not possible_keys: output_data["ERROR"] = "keys_not_found" else: # We show the number of keys found (and those # keys too, of course). output_data[f"possible key"] = ", ".join(possible_keys) else: # Handling errors. output_data["ERROR"] = input_data["ERROR"] return output_data
def get_hash(hash_function, mode, new=False): """ The main function for almost all the hashing functions. It was defined since almost all the hashing algorithms in this program have the same pattern of the code. """ # We have the argument "new" since there are some functions # executable only by hashlib.new(name). output_data = dict() if mode == "man": output_data["manual"] = globals()[hash_function + "_manual"]() return output_data # Getting all the data required to implement a hash function. input_data = get_input_data( ALL_FUNCTIONS["hashing"]["functions"][hash_function][mode]) if "ERROR" not in input_data: # We have to decide here whether we calculate # the hash sum of a file or text. if "text" in input_data: target = output_data["plaintext"] = input_data["text"] elif "file" in input_data: target = output_data["file"] = input_data["file"] ## Hashing. # Checking whether a function defined as a # "new" one or not in the hashlib module. if new: result = hashlib.new(hash_function) else: result = getattr(hashlib, hash_function)() if mode == "hash_str": result.update(target.encode("UTF-8")) if input_data["salt_y_or_n"] == "y": # The length of a salt must be equal to the digest # size. salt = output_data["salt"] = random_string( len(result.hexdigest())) result.update(salt.encode("UTF-8")) elif mode == "hash_file": with open(target, "rb") as file: if (getsize(target) / 1024 / 1024) >= 1024: # If the file size is greater than or equal to # 1 gigabyte, we apply a hash function to the # file through blocks. BLOCKSIZE = 2**20 content = file.read(BLOCKSIZE) while len(content) > 0: result.update(content) content = file.read(BLOCKSIZE) else: content = file.read() result.update(content) output_data["hash sum"] = result.hexdigest() else: # Handling errors. output_data["ERROR"] = input_data["ERROR"] return output_data