diff --git a/Readme.md b/Readme.md index 4f2ab48..d310b0e 100644 --- a/Readme.md +++ b/Readme.md @@ -33,7 +33,7 @@ python scripts/main.py --mode cleanup --user "1" && python scripts/main.py --mo - Plattform independend - easy to use -# setup +# required software ```bash pip install numpy gpg @@ -41,6 +41,10 @@ python scripts/main.py --mode cleanup --user "1" && python scripts/main.py --mo pip ``` +## todo +- Implement cleanup +- implement relativ call + ## Further Information - https://www.tutorialspoint.com/python/python_command_line_arguments.htm - https://docs.python.org/3/library/argparse.html#module-argparse diff --git a/scripts/classes/AbstractSplittedSecret.py b/scripts/classes/AbstractSplittedSecret.py index 79d50c9..a7c26b1 100644 --- a/scripts/classes/AbstractSplittedSecret.py +++ b/scripts/classes/AbstractSplittedSecret.py @@ -1,11 +1,23 @@ from .Cli import Cli class AbstractSplittedSecret(Cli): + USER_PASSWORD_LENGTHS = 64 + OVERALL_PASSWORD_LENGTHS = 128 + + # At the moment the programm can used deal with one digit numbers. + MAXIMUM_SECRET_HOLDERS = 9 + MINIMUM_SECRET_HOLDERS = 2 def __init__(self): super(Cli, self).__init__() self.data_folder = "data/" + def getCoSecretHoldersRange(): + return range(AbstractSplittedSecret.MINIMUM_SECRET_HOLDERS,AbstractSplittedSecret.MAXIMUM_SECRET_HOLDERS) + + def getSecretHoldersRange(): + return range(1,AbstractSplittedSecret.MAXIMUM_SECRET_HOLDERS) + def getFolderPath(self,folder_type): return self.data_folder + folder_type + "/" diff --git a/scripts/classes/Cli.py b/scripts/classes/Cli.py index eec05c9..d75388b 100644 --- a/scripts/classes/Cli.py +++ b/scripts/classes/Cli.py @@ -19,8 +19,7 @@ class Cli(object): for line in stdout: self.output.append(line.decode("utf-8")) if process.wait() > bool(0): - print(command, out, err) - raise Exception("Exitcode is greater then 0") + raise Exception("Error for: \nCommand:<<" + command + ">>\nOutput:<<" + out + ">>\nExitcode:<<" + err + ">>") return self.output def getOutputString(self): diff --git a/scripts/classes/Decryption.py b/scripts/classes/Decryption.py index 04b8a36..2ee6200 100644 --- a/scripts/classes/Decryption.py +++ b/scripts/classes/Decryption.py @@ -7,12 +7,47 @@ class Decryption(AbstractSplittedSecret): self.user_password='' super(Decryption, self).__init__() - def setUserId(self,user_id): + def initializeUser(self,user_id): self.user_id=str(user_id) self.user_file_decrypted_path = self.getUserFilePath(self.user_id,"decrypted") + + def initializeUserDataDecryption(self): + self.decryptUserFile() + self.user_data = self.loadJsonFile(self.user_file_decrypted_path) + self.initializeNeededDecryptersAmount() + self.initializeValidDecrypterIds() + + def initializeNeededDecryptersAmount(self): + self.needed_decrypters_amount = len(str(list(self.user_data['groups'].keys())[0])) + + def initializeValidDecrypterIds(self): + self.valid_decrypter_ids = [] + self.valid_decrypter_ids.append(int(self.user_id)) + for contact_id in self.user_data['contacts']: + self.valid_decrypter_ids.append(int(contact_id)) def setUserPassword(self,user_password): self.user_password = str(user_password) + + def resetDecrypterIds(self): + self.decrypter_ids = [] + self.addDecrypterId(self.user_id) + + def addDecrypterId(self,decrypter_id): + decrypter_id = int(decrypter_id) + if decrypter_id not in self.valid_decrypter_ids: + raise Exception("The encrypter id is not valid. Valid encrypter ids are: " + str(self.valid_decrypter_ids)) + if len(self.decrypter_ids) >= self.needed_decrypters_amount: + raise Exception("There are already sufficients decrypters (" + str(len(self.decrypter_ids)) + ") defined!") + if decrypter_id in self.decrypter_ids: + raise Exception("The decrypter is already in the list.") + self.decrypter_ids.append(decrypter_id) + + def getDecryptersIds(self): + return self.decrypter_ids + + def getNeededCoDecryptersAmount(self): + return self.needed_decrypters_amount -1 def loadJsonFile(self,file_path): file = open(file_path) @@ -20,9 +55,6 @@ class Decryption(AbstractSplittedSecret): file.close() return data - def setNeededEncryptersAmount(self): - self.needed_encrypters_amount = len(str(list(self.user_data['groups'].keys())[0]))-1 - def decryptFile(self,password,input_file_path,output_file_path): self.executeCommand('gpg --batch --passphrase "'+ password + '" -o "' + output_file_path +'" "'+ input_file_path+'"') @@ -33,9 +65,4 @@ class Decryption(AbstractSplittedSecret): def decryptAccumulatedFile(self): input_file_path = self.getAccumulatedFilePath("encrypted") output_file_path = self.getAccumulatedFilePath("decrypted") - self.decryptFile(self.user_password, input_file_path, output_file_path) - - def initializeData(self): - self.decryptUserFile() - self.user_data = self.loadJsonFile(self.user_file_decrypted_path) - self.setNeededEncryptersAmount() \ No newline at end of file + self.decryptFile(self.user_password, input_file_path, output_file_path) \ No newline at end of file diff --git a/scripts/classes/Encryption.py b/scripts/classes/Encryption.py index b2c0b3c..f8ba2df 100644 --- a/scripts/classes/Encryption.py +++ b/scripts/classes/Encryption.py @@ -22,7 +22,7 @@ class Encryption(AbstractSplittedSecret): self.user_mapped_data = {} user_count = 1 while user_count <= self.amount_of_secret_holders: - self.user_mapped_data[str(user_count)] = {"groups":{},"user_password":self.createPassword(64),"about":{}} + self.user_mapped_data[str(user_count)] = {"groups":{},"user_password":self.createPassword(self.USER_PASSWORD_LENGTHS),"about":{}} user_count += 1; def initializeGroupData(self): @@ -81,7 +81,7 @@ class Encryption(AbstractSplittedSecret): password = '' for secret_holder_index in password_group_index_str: self.group_mapped_data[password_group_index_int]['members'][secret_holder_index]={} - particial_password_length= int(128*self.quota_factor); + particial_password_length= int(self.OVERALL_PASSWORD_LENGTHS*self.quota_factor); password_part = self.createPassword(particial_password_length) self.group_mapped_data[password_group_index_int]['members'][secret_holder_index] = password_part password += password_part diff --git a/scripts/main.py b/scripts/main.py index 8f50091..72d07c0 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -3,15 +3,16 @@ from classes.Encryption import Encryption from classes.Cleanup import Cleanup from classes.Decryption import Decryption from getpass import getpass +from classes.AbstractSplittedSecret import AbstractSplittedSecret if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--mode',type=str, dest='mode',required=True,choices=['cleanup','encrypt','decrypt']) - parser.add_argument('--amount',type=int, dest='amount_of_secret_holders',required=False,choices=range(1,9)) + parser.add_argument('--amount',type=int, dest='amount_of_secret_holders',required=False,choices=AbstractSplittedSecret.getCoSecretHoldersRange()) parser.add_argument('--quota', type=int, dest='decryption_quota', choices=range(1,101),required=False) parser.add_argument('--master-password',type=str, dest='master_password',required=False) parser.add_argument('--user-password',type=str, dest='user_password',required=False) - parser.add_argument('--user',type=int, dest='user',choices=range(1,9),required=False) + parser.add_argument('--user',type=int, dest='user',choices=AbstractSplittedSecret.getSecretHoldersRange(),required=False) parser.add_argument('--add-user-information',type=bool, dest='add_user_information', default=False, required=False, action=argparse.BooleanOptionalAction) args = parser.parse_args() mode = args.mode @@ -34,26 +35,26 @@ if __name__ == '__main__': if args.master_password is None: if args.user is None: print("Please type in the user number:") - decrypt.setUserId(input()) + decrypt.initializeUser(input()) else: - decrypt.setUserId(args.user) + decrypt.initializeUser(args.user) if args.user_password is None: while True: print("Please enter the user password:") decrypt.setUserPassword(getpass()) print("Decrypting User File...") try: - decrypt.initializeData(); + decrypt.initializeUserDataDecryption(); break; - except: - print("Wrong password :(") + except Exception as error: + print("An error occured. Propably you typed in a wrong password :( The error is: " + str(error)) else: decrypt.setUserPassword(args.user_password) print("Decrypting User File...") try: - decrypt.initializeData(); - except: - print("Wrong password :(") + decrypt.initializeUserDataDecryption(); + except Exception as error: + print("An error occured. Propably you passed a wrong password :( The error is: " + str(error)) exit() print("File decrypted :) \n") print("Please contact the following persons and tell them that you need help to encrypt the data: \n") @@ -61,8 +62,21 @@ if __name__ == '__main__': print("user_id: " + contact_id) for label in decrypt.user_data['contacts'][contact_id]: print(label + ": " + decrypt.user_data['contacts'][contact_id][label]) - print("You need at least <<" + str(decrypt.needed_encrypters_amount) +">> other person to decrypt the secret.") - exit() + print("--------------------------------\n") + while True: + decrypt.resetDecrypterIds() + try: + person_counter = 1 + while person_counter <= decrypt.getNeededCoDecryptersAmount(): + print("The following user id's are in the decryption list: " + str(decrypt.getDecryptersIds())) + print("You need at least <<" + str(decrypt.getNeededCoDecryptersAmount()) +">> other person to decrypt the secret.") + print("Type in the user id of another encrypter:") + decrypt.addDecrypterId(int(input())) + person_counter += 1 + break + except Exception as error: + print("The following error occured <<" + str(error) + ">> :( \n Please try again :)") + exit() print("Decrypting accumulated file...") decrypt.setUserPassword(args.master_password) decrypt.decryptAccumulatedFile()