mirror of
https://github.com/kevinveenbirkenbach/splitted-secret.git
synced 2024-11-22 02:01:05 +01:00
Compare commits
3 Commits
a88ca6904a
...
a0c17c9fd6
Author | SHA1 | Date | |
---|---|---|---|
a0c17c9fd6 | |||
b3bd3a0095 | |||
11848ba222 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
|||||||
__pycache__
|
__pycache__
|
||||||
testcases.txt
|
INSTRUCTIONS.md
|
@ -40,15 +40,23 @@ To delete all encrypted data execute:
|
|||||||
python scripts/main.py --mode cleanup --file-types encrypted
|
python scripts/main.py --mode cleanup --file-types encrypted
|
||||||
```
|
```
|
||||||
|
|
||||||
## decrypt
|
## decrypt
|
||||||
|
|
||||||
### decrypt automatic
|
### decrypt automatic
|
||||||
To decrypt the data execute:
|
To decrypt the data execute:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/main.py --mode decrypt
|
python scripts/main.py --mode decrypt-data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### decrypt accumulated file
|
||||||
|
To decrypt the accumulated datafile execute:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/main.py --mode decrypt --meta
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### decrypt defined user
|
### decrypt defined user
|
||||||
To decrypt the data for a defined user execute:
|
To decrypt the data for a defined user execute:
|
||||||
|
|
||||||
@ -56,18 +64,19 @@ To decrypt the data for a defined user execute:
|
|||||||
python scripts/main.py --mode decrypt --user "<<user_id>>"
|
python scripts/main.py --mode decrypt --user "<<user_id>>"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### addtional instructions
|
||||||
|
In the [INSTRUCTIONS.md](./Instruction.md) file the master encrypter can leave additional instructions.
|
||||||
|
|
||||||
## encrypt
|
## encrypt
|
||||||
|
|
||||||
### encrypt main data
|
### encrypt main data
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/main.py --secret-holders-amount "<<amount>>" --quota "<<quota>>" --mode encrypt --master-password "<<master_password>>" --input-directory "<<input_directory>>"
|
python scripts/main.py --secret-holders-amount "<<amount>>" --quota "<<quota>>" --mode encrypt --master-password "<<master_password>>" --input-directory "<<input_directory>>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### encrypt master password
|
### encrypt master password
|
||||||
|
|
||||||
To encrypt the master-password file and to create the neccessary encrypted meta data execute:
|
To encrypt the master-password file and to create the neccessary encrypted meta data execute:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/main.py --secret-holders-amount "<<amount>>" --quota "<<quota>>" --mode encrypt --add-user-information --master-password "<<master_password>>" --create-meta-data
|
python scripts/main.py --secret-holders-amount "<<amount>>" --quota "<<quota>>" --mode encrypt --add-user-information --master-password "<<master_password>>" --meta
|
||||||
```
|
```
|
@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import shlex
|
||||||
|
|
||||||
class AutomaticIdentificationImpossibleException(Exception):
|
class AutomaticIdentificationImpossibleException(Exception):
|
||||||
pass
|
pass
|
||||||
@ -35,12 +36,18 @@ class Decryption():
|
|||||||
self.initializeNeededDecryptersAmount()
|
self.initializeNeededDecryptersAmount()
|
||||||
self.initializeValidDecrypterIds()
|
self.initializeValidDecrypterIds()
|
||||||
|
|
||||||
|
def getEscapedMasterPassword(self):
|
||||||
|
return shlex.quote(self.master_password)
|
||||||
|
|
||||||
def initializeGroupDataEncryption(self):
|
def initializeGroupDataEncryption(self):
|
||||||
self.group_name = self.getDecryptersGroupName()
|
self.group_name = self.getDecryptersGroupName()
|
||||||
self.encrypted_group_file_path = self.paths.getGroupFilePath(self.group_name, self.paths.TYPE_DECRYPTED)
|
self.encrypted_group_file_path = self.paths.getGroupFilePath(self.group_name, self.paths.TYPE_DECRYPTED)
|
||||||
self.decryptGroupFile()
|
self.decryptGroupFile()
|
||||||
self.master_password = self.loadTxtFile(self.encrypted_group_file_path).strip()
|
self.master_password = self.loadTxtFile(self.encrypted_group_file_path).strip()
|
||||||
|
|
||||||
|
def getMasterPassword(self):
|
||||||
|
return self.master_password
|
||||||
|
|
||||||
def initializeNeededDecryptersAmount(self):
|
def initializeNeededDecryptersAmount(self):
|
||||||
self.needed_decrypters_amount = len(str(list(self.user_data['groups'].keys())[0]))
|
self.needed_decrypters_amount = len(str(list(self.user_data['groups'].keys())[0]))
|
||||||
|
|
||||||
@ -70,9 +77,6 @@ class Decryption():
|
|||||||
shared_password += str(self.password_parts[password_share_index])
|
shared_password += str(self.password_parts[password_share_index])
|
||||||
return shared_password
|
return shared_password
|
||||||
|
|
||||||
def getMasterPassword(self):
|
|
||||||
return self.master_password
|
|
||||||
|
|
||||||
def addDecrypterId(self,decrypter_id):
|
def addDecrypterId(self,decrypter_id):
|
||||||
decrypter_id = int(decrypter_id)
|
decrypter_id = int(decrypter_id)
|
||||||
if decrypter_id not in self.valid_decrypter_ids:
|
if decrypter_id not in self.valid_decrypter_ids:
|
||||||
@ -114,7 +118,7 @@ class Decryption():
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def decryptFile(self,password,input_file_path,output_file_path):
|
def decryptFile(self,password,input_file_path,output_file_path):
|
||||||
self.cli.executeCommand('gpg --batch --passphrase "'+ password + '" -o "' + output_file_path +'" "'+ input_file_path+'"')
|
self.cli.executeCommand('gpg --batch --passphrase '+ shlex.quote(password) + ' -o "' + output_file_path +'" "'+ input_file_path+'"')
|
||||||
|
|
||||||
def decryptUserFile(self):
|
def decryptUserFile(self):
|
||||||
input_file_path = self.paths.getUserFilePath(self.user_id,self.paths.TYPE_ENCRYPTED)
|
input_file_path = self.paths.getUserFilePath(self.user_id,self.paths.TYPE_ENCRYPTED)
|
||||||
@ -130,4 +134,4 @@ class Decryption():
|
|||||||
self.decryptFile(self.user_password, input_file_path, output_file_path)
|
self.decryptFile(self.user_password, input_file_path, output_file_path)
|
||||||
|
|
||||||
def decryptMainData(self):
|
def decryptMainData(self):
|
||||||
self.cli.executeCommand('gpg --batch --passphrase "' + self.getMasterPassword() + '" -d "' + self.paths.getEncryptedMainDataFile() + '" | tar --one-top-level="' + self.paths.getDecryptedMainDataStandartFolder() + '" -xvzf -')
|
self.cli.executeCommand('gpg --batch --passphrase ' + shlex.quote(self.getMasterPassword()) + ' -d "' + self.paths.getEncryptedMainDataFile() + '" | tar --one-top-level="' + self.paths.getDecryptedMainDataStandartFolder() + '" -xvzf -')
|
@ -5,6 +5,7 @@ import numpy
|
|||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
from .Paths import Paths
|
from .Paths import Paths
|
||||||
|
import shlex
|
||||||
|
|
||||||
class Encryption():
|
class Encryption():
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ class Encryption():
|
|||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
def encryptStringToFile(self,text,output_file,password):
|
def encryptStringToFile(self,text,output_file,password):
|
||||||
self.cli.executeCommand('echo \'' + text + '\' | gpg --symmetric --armor --batch --passphrase "' + password + '" -o "' + output_file + '"')
|
self.cli.executeCommand('echo ' + shlex.quote(text) + ' | gpg --symmetric --armor --batch --passphrase ' + shlex.quote(password) + ' -o "' + output_file + '"')
|
||||||
|
|
||||||
def encryptGroupFiles(self):
|
def encryptGroupFiles(self):
|
||||||
for password_group_index_int in self.group_mapped_data:
|
for password_group_index_int in self.group_mapped_data:
|
||||||
@ -125,7 +126,7 @@ class Encryption():
|
|||||||
See: https://stackoverflow.com/questions/30650841/why-am-i-getting-errno-7-argument-list-too-long-and-oserror-errno-24-too-ma
|
See: https://stackoverflow.com/questions/30650841/why-am-i-getting-errno-7-argument-list-too-long-and-oserror-errno-24-too-ma
|
||||||
'''
|
'''
|
||||||
def encryptFileToFile(self,input_file,output_file,password):
|
def encryptFileToFile(self,input_file,output_file,password):
|
||||||
self.cli.executeCommand('cat \'' + input_file + '\' | gpg --symmetric --armor --batch --passphrase "' + password + '" -o "' + output_file + '"')
|
self.cli.executeCommand('cat \'' + input_file + '\' | gpg --symmetric --armor --batch --passphrase ' + shlex.quote(password) + ' -o "' + output_file + '"')
|
||||||
|
|
||||||
def deleteDecryptedAccumulatedFile(self):
|
def deleteDecryptedAccumulatedFile(self):
|
||||||
self.cli.executeCommand('rm ' + self.paths.getAccumulatedFilePath(Paths.TYPE_DECRYPTED))
|
self.cli.executeCommand('rm ' + self.paths.getAccumulatedFilePath(Paths.TYPE_DECRYPTED))
|
||||||
@ -144,7 +145,7 @@ class Encryption():
|
|||||||
self.deleteDecryptedAccumulatedFile()
|
self.deleteDecryptedAccumulatedFile()
|
||||||
|
|
||||||
def encryptMainData(self,input_directory):
|
def encryptMainData(self,input_directory):
|
||||||
self.cli.executeCommand('tar -C"' + input_directory + '" -cvzf - ./ | gpg -c --batch --passphrase "' + self.master_password +'" > "' + self.paths.getEncryptedMainDataFile() + '"')
|
self.cli.executeCommand('tar -C"' + input_directory + '" -cvzf - ./ | gpg -c --batch --passphrase ' + shlex.quote(self.master_password) + ' > "' + self.paths.getEncryptedMainDataFile() + '"')
|
||||||
|
|
||||||
def encryptMetaData(self):
|
def encryptMetaData(self):
|
||||||
self.encryptUserFile()
|
self.encryptUserFile()
|
||||||
|
160
scripts/main.py
160
scripts/main.py
@ -40,11 +40,13 @@ try:
|
|||||||
parser.add_argument('--user',type=int, dest='user',choices=Encryption.getSecretHoldersRange(),required=False)
|
parser.add_argument('--user',type=int, dest='user',choices=Encryption.getSecretHoldersRange(),required=False)
|
||||||
parser.add_argument('--add-user-information',type=bool, dest='add_user_information', default=False, required=False, action=argparse.BooleanOptionalAction, help="Add additional information to users.")
|
parser.add_argument('--add-user-information',type=bool, dest='add_user_information', default=False, required=False, action=argparse.BooleanOptionalAction, help="Add additional information to users.")
|
||||||
parser.add_argument('--input-directory',type=str,dest='input_directory',required=False, help="The directory from which the data should be encrypted.")
|
parser.add_argument('--input-directory',type=str,dest='input_directory',required=False, help="The directory from which the data should be encrypted.")
|
||||||
parser.add_argument('--create-meta-data',type=bool, dest='create_meta_data', default=False, required=False, action=argparse.BooleanOptionalAction, help="When mode is encrypt and this flag is set, the encrypted meta data is created.")
|
parser.add_argument('--meta-data',type=bool, dest='meta_data', default=False, required=False, action=argparse.BooleanOptionalAction, help="When mode is encrypt and this flag is set, the encrypted meta data is created. When mode is decrypt and this flag is set the accumulated file will be decrypted.")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
print("Application started.")
|
print("Application started.")
|
||||||
print("To leave the appplication use the key kombination: <<Ctr>> + <<Alt>> + <<C>>")
|
print("To leave the appplication use the key kombination: <<Ctr>> + <<Alt>> + <<C>>")
|
||||||
|
print("Cleaning up all decrypted files.")
|
||||||
|
cleanup.cleanupFiles(Paths.TYPE_DECRYPTED)
|
||||||
print("Selected Mode: " + args.mode)
|
print("Selected Mode: " + args.mode)
|
||||||
|
|
||||||
if args.mode == 'cleanup':
|
if args.mode == 'cleanup':
|
||||||
@ -63,85 +65,91 @@ try:
|
|||||||
|
|
||||||
if args.mode == 'decrypt':
|
if args.mode == 'decrypt':
|
||||||
decrypt = Decryption(cli,paths)
|
decrypt = Decryption(cli,paths)
|
||||||
if args.master_password is None:
|
if args.meta_data is True:
|
||||||
if args.user is None:
|
if args.master_password is None:
|
||||||
try:
|
print("Enter the master password:")
|
||||||
print("Attempt to identify user.")
|
master_password = getpass()
|
||||||
user_id = decrypt.identifyUser()
|
|
||||||
print("The user id is: " + user_id)
|
|
||||||
except:
|
|
||||||
print("A automatic user id identification wasn't possible.")
|
|
||||||
print("Type in the user id:")
|
|
||||||
user_id = input()
|
|
||||||
decrypt.initializeUser(user_id)
|
|
||||||
else:
|
else:
|
||||||
decrypt.initializeUser(args.user)
|
master_password = args.master_password
|
||||||
if args.user_password is None:
|
decrypt = Decryption(cli,paths)
|
||||||
while True:
|
print("Decrypting accumulated data.")
|
||||||
print("Enter the user password:")
|
decrypt.setUserPassword(master_password)
|
||||||
decrypt.setUserPassword(getpass())
|
decrypt.decryptAccumulatedFile()
|
||||||
print("Decrypting User File...")
|
dirty_exit()
|
||||||
try:
|
if args.user is None:
|
||||||
decrypt.initializeUserDataDecryption();
|
try:
|
||||||
break;
|
print("Attempt to identify user.")
|
||||||
except Exception as error:
|
user_id = decrypt.identifyUser()
|
||||||
print("An error occured. Propably you typed in a wrong password :( The error is: " + str(error))
|
print("The user id is: " + user_id)
|
||||||
else:
|
except:
|
||||||
decrypt.setUserPassword(args.user_password)
|
print("A automatic user id identification wasn't possible.")
|
||||||
|
print("Type in the user id:")
|
||||||
|
user_id = input()
|
||||||
|
decrypt.initializeUser(user_id)
|
||||||
|
else:
|
||||||
|
decrypt.initializeUser(args.user)
|
||||||
|
if args.user_password is None:
|
||||||
|
while True:
|
||||||
|
print("Enter the user password:")
|
||||||
|
decrypt.setUserPassword(getpass())
|
||||||
print("Decrypting User File...")
|
print("Decrypting User File...")
|
||||||
try:
|
try:
|
||||||
decrypt.initializeUserDataDecryption();
|
decrypt.initializeUserDataDecryption();
|
||||||
except Exception as error:
|
|
||||||
print("An error occured. Propably you passed a wrong password :( The error is: " + str(error))
|
|
||||||
clean_exit()
|
|
||||||
print("\nContact the following persons and request their password share: \n")
|
|
||||||
for contact_id in decrypt.user_data['contacts']:
|
|
||||||
print("user_id: " + contact_id)
|
|
||||||
for label in decrypt.user_data['contacts'][contact_id]:
|
|
||||||
print(label + ": " + decrypt.user_data['contacts'][contact_id][label])
|
|
||||||
while True:
|
|
||||||
print("\nReset password shares.\n")
|
|
||||||
decrypt.resetDecrypterIds()
|
|
||||||
try:
|
|
||||||
password_shares_count = 1
|
|
||||||
while password_shares_count < decrypt.getNeededDecryptersAmount():
|
|
||||||
print(str(password_shares_count) + " password shares had been added.")
|
|
||||||
print("Password shares for the the users " + str(decrypt.getDecrypterIds()) + " been added. ")
|
|
||||||
print("You need to add " + str((decrypt.getNeededDecryptersAmount()-password_shares_count)) +" more password shares.")
|
|
||||||
print("\nType in the user id of another decrypter:")
|
|
||||||
decrypt.addDecrypterId(int(input()))
|
|
||||||
password_shares_count += 1
|
|
||||||
break
|
|
||||||
except Exception as error:
|
|
||||||
print("The following error occured <<" + str(error) + ">> :( \n Try again :)")
|
|
||||||
print("\nYour data is:\n")
|
|
||||||
print("FOR PASSWORD GROUP: " + decrypt.getDecryptersGroupName())
|
|
||||||
print("FOR USER ID: " + decrypt.getUserId())
|
|
||||||
print("PASSWORD SHARE IS: " + decrypt.getPasswordShare() + "\n")
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
decrypt.resetPasswordShare()
|
|
||||||
co_decrypter_ids = decrypt.getCoDecrypterIds()
|
|
||||||
for co_decrypter_id in decrypt.getCoDecrypterIds():
|
|
||||||
print("Type in the password share for: \n")
|
|
||||||
print("FOR PASSWORD GROUP: " + decrypt.getDecryptersGroupName())
|
|
||||||
print("FOR USER: " + str(co_decrypter_id))
|
|
||||||
print("PASSWORD SHARE IS: ")
|
|
||||||
decrypt.addPasswordShare(co_decrypter_id, input())
|
|
||||||
print("\nTHE GROUP PASSWORD IS: " + decrypt.getGroupPassword())
|
|
||||||
print("\nDecrypting group password file.\n")
|
|
||||||
decrypt.initializeGroupDataEncryption()
|
|
||||||
print("THE MASTER PASSWORD IS: " + decrypt.getMasterPassword())
|
|
||||||
break;
|
break;
|
||||||
except:
|
except Exception as error:
|
||||||
print("An unexpected error occured: \n" + traceback.format_exc())
|
print("An error occured. Propably you typed in a wrong password :( The error is: " + str(error))
|
||||||
print("Decrypting main data.")
|
else:
|
||||||
decrypt.decryptMainData()
|
decrypt.setUserPassword(args.user_password)
|
||||||
print("The data was decrypted to: " + paths.getDecryptedMainDataStandartFolder())
|
print("Decrypting User File...")
|
||||||
dirty_exit()
|
try:
|
||||||
print("Decrypting accumulated data.")
|
decrypt.initializeUserDataDecryption();
|
||||||
decrypt.setUserPassword(args.master_password)
|
except Exception as error:
|
||||||
decrypt.decryptAccumulatedFile()
|
print("An error occured. Propably you passed a wrong password :( The error is: " + str(error))
|
||||||
|
clean_exit()
|
||||||
|
print("\nContact the following persons and request their password share: \n")
|
||||||
|
for contact_id in decrypt.user_data['contacts']:
|
||||||
|
print("user_id: " + contact_id)
|
||||||
|
for label in decrypt.user_data['contacts'][contact_id]:
|
||||||
|
print(label + ": " + decrypt.user_data['contacts'][contact_id][label])
|
||||||
|
while True:
|
||||||
|
print("\nReset password shares.\n")
|
||||||
|
decrypt.resetDecrypterIds()
|
||||||
|
try:
|
||||||
|
password_shares_count = 1
|
||||||
|
while password_shares_count < decrypt.getNeededDecryptersAmount():
|
||||||
|
print(str(password_shares_count) + " password shares had been added.")
|
||||||
|
print("Password shares for the the users " + str(decrypt.getDecrypterIds()) + " been added. ")
|
||||||
|
print("You need to add " + str((decrypt.getNeededDecryptersAmount()-password_shares_count)) +" more password shares.")
|
||||||
|
print("\nType in the user id of another decrypter:")
|
||||||
|
decrypt.addDecrypterId(int(input()))
|
||||||
|
password_shares_count += 1
|
||||||
|
break
|
||||||
|
except Exception as error:
|
||||||
|
print("The following error occured <<" + str(error) + ">> :( \n Try again :)")
|
||||||
|
print("\nYour data is:\n")
|
||||||
|
print("FOR PASSWORD GROUP: " + decrypt.getDecryptersGroupName())
|
||||||
|
print("FOR USER ID: " + decrypt.getUserId())
|
||||||
|
print("PASSWORD SHARE IS: " + decrypt.getPasswordShare() + "\n")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
decrypt.resetPasswordShare()
|
||||||
|
co_decrypter_ids = decrypt.getCoDecrypterIds()
|
||||||
|
for co_decrypter_id in decrypt.getCoDecrypterIds():
|
||||||
|
print("Type in the password share for: \n")
|
||||||
|
print("FOR PASSWORD GROUP: " + decrypt.getDecryptersGroupName())
|
||||||
|
print("FOR USER: " + str(co_decrypter_id))
|
||||||
|
print("PASSWORD SHARE IS: ")
|
||||||
|
decrypt.addPasswordShare(co_decrypter_id, input())
|
||||||
|
print("\nTHE GROUP PASSWORD IS: " + decrypt.getGroupPassword())
|
||||||
|
print("\nDecrypting group password file.\n")
|
||||||
|
decrypt.initializeGroupDataEncryption()
|
||||||
|
print("THE MASTER PASSWORD IS: " + decrypt.getMasterPassword())
|
||||||
|
break;
|
||||||
|
except:
|
||||||
|
print("An unexpected error occured: \n" + traceback.format_exc())
|
||||||
|
print("Decrypting main data.")
|
||||||
|
decrypt.decryptMainData()
|
||||||
|
print("The data was decrypted to: " + paths.getDecryptedMainDataStandartFolder())
|
||||||
dirty_exit()
|
dirty_exit()
|
||||||
|
|
||||||
if args.mode == 'encrypt':
|
if args.mode == 'encrypt':
|
||||||
@ -157,7 +165,7 @@ try:
|
|||||||
print("Enter attribut <<" + label + ">> for user <<" + user_id+ ">>:" )
|
print("Enter attribut <<" + label + ">> for user <<" + user_id+ ">>:" )
|
||||||
encrypt.addInformationToUser(user_id, label, str(input()))
|
encrypt.addInformationToUser(user_id, label, str(input()))
|
||||||
encrypt.compileData()
|
encrypt.compileData()
|
||||||
if args.create_meta_data is True:
|
if args.meta_data is True:
|
||||||
print("Create and encrypt meta data.")
|
print("Create and encrypt meta data.")
|
||||||
encrypt.encryptMetaData()
|
encrypt.encryptMetaData()
|
||||||
if args.input_directory is not None:
|
if args.input_directory is not None:
|
||||||
|
Loading…
Reference in New Issue
Block a user