On running test the sript generates 3 user where password == username
All checks were successful
continuous-integration/drone/push Build is passing

->  user1: 'alma' with passphrase: 'amla'
    ->  user2: 'citrom' with passphrase: 'mortic'
    ->  user1: 'dinnye' with passphrase: 'eynnid'

The private keys are envrypted in DER format with pkcs#8 using the passphrase.
The private keys are temporarly stored under config/{homeDir}
The public keys are stored in the config file without encryption
This commit is contained in:
DESKTOP-DPA61F8\Benedek 2021-04-18 18:59:01 +02:00
parent 2f011de6f7
commit 81211b1dd5
2 changed files with 61 additions and 11 deletions

View File

@ -4,7 +4,7 @@ import os
import shutil import shutil
import sys import sys
from base64 import b64encode from base64 import b64encode
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256 from Crypto.Hash import SHA256
from Crypto.Protocol.KDF import bcrypt, bcrypt_check from Crypto.Protocol.KDF import bcrypt, bcrypt_check
@ -16,6 +16,7 @@ class Authetication:
ABSOLUTE_PATH = os.path.abspath(os.path.dirname(sys.argv[0])) ABSOLUTE_PATH = os.path.abspath(os.path.dirname(sys.argv[0]))
HOME_DIRECTORY_LOCATION = ABSOLUTE_PATH + "\\home" HOME_DIRECTORY_LOCATION = ABSOLUTE_PATH + "\\home"
CONFIG_DIRECTORY_LOCATION = ABSOLUTE_PATH + "\\config" CONFIG_DIRECTORY_LOCATION = ABSOLUTE_PATH + "\\config"
PRIVATE_KEY_DIRECTORY_LOCATION = CONFIG_DIRECTORY_LOCATION + "\\private_keys"
USER_INDEX = 0 USER_INDEX = 0
def __init__(self): def __init__(self):
@ -25,6 +26,9 @@ class Authetication:
if not os.path.isdir(self.CONFIG_DIRECTORY_LOCATION): if not os.path.isdir(self.CONFIG_DIRECTORY_LOCATION):
os.mkdir(self.CONFIG_DIRECTORY_LOCATION) os.mkdir(self.CONFIG_DIRECTORY_LOCATION)
if not os.path.isdir(self.PRIVATE_KEY_DIRECTORY_LOCATION):
os.mkdir(self.PRIVATE_KEY_DIRECTORY_LOCATION)
if not os.path.isfile(self.CONFIG_DIRECTORY_LOCATION + "\\config.txt") or os.stat( if not os.path.isfile(self.CONFIG_DIRECTORY_LOCATION + "\\config.txt") or os.stat(
self.CONFIG_DIRECTORY_LOCATION + "\\config.txt").st_size == 0: self.CONFIG_DIRECTORY_LOCATION + "\\config.txt").st_size == 0:
data = {'index': 0, 'user': []} data = {'index': 0, 'user': []}
@ -63,6 +67,37 @@ class Authetication:
shutil.rmtree(self.HOME_DIRECTORY_LOCATION) shutil.rmtree(self.HOME_DIRECTORY_LOCATION)
os.mkdir(self.HOME_DIRECTORY_LOCATION) os.mkdir(self.HOME_DIRECTORY_LOCATION)
shutil.rmtree(self.PRIVATE_KEY_DIRECTORY_LOCATION)
os.mkdir(self.PRIVATE_KEY_DIRECTORY_LOCATION)
def generatePrivateKeyForUser(self, username:str, user_passphrase:str) -> bool:
if self.checkUserExists(username):
with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt') as json_file:
data = json.load(json_file)
private_key = RSA.generate(2048)
public_key = private_key.publickey()
private_key_value = str(private_key.export_key('DER', passphrase=user_passphrase, pkcs=8))
public_key_value = str(public_key.export_key('DER', pkcs=8))
##Save private key in separate file
user_privatekey = {'passphrase': user_passphrase, 'privateKey': private_key_value}
with open(self.PRIVATE_KEY_DIRECTORY_LOCATION + '\\' + str(data['index']) + '.txt', 'w+') as outfile:
json.dump(user_privatekey, outfile)
##Save public key in users
for user in data['user']:
if username == user['username']:
user['publicKey'] = public_key_value
with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt', 'w') as outfile:
json.dump(data, outfile)
break
return True
else:
return False
def saveUser(self, username: str, password: str) -> bool: def saveUser(self, username: str, password: str) -> bool:
bytePass = password.encode('utf-8') bytePass = password.encode('utf-8')
@ -72,23 +107,27 @@ class Authetication:
with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt') as json_file: with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt') as json_file:
data = json.load(json_file) data = json.load(json_file)
user = {
'username': username,
'password': bcrypt_hash.decode('utf-8'),
'homeDir': str(data['index'] + 1)
}
data['index'] = data['index'] + 1
if self.checkUserExists(username): if self.checkUserExists(username):
auth_logger.debug("User NOT saved! This username already exists!") auth_logger.debug("User NOT saved! This username already exists!")
return False return False
else: else:
if not os.path.isdir(self.HOME_DIRECTORY_LOCATION + "\\" + str(user['homeDir'])): if not os.path.isdir(self.HOME_DIRECTORY_LOCATION + "\\" + str(data['index'] + 1)):
os.mkdir(self.HOME_DIRECTORY_LOCATION + "\\" + str(user['homeDir'])) data['index'] = data['index'] + 1
user = {
'username': username,
'password': bcrypt_hash.decode('utf-8'),
'homeDir': str(data['index']),
'publicKey': ''
}
##Create user HOME directory with index as name
os.mkdir(self.HOME_DIRECTORY_LOCATION + '\\' + str(data['index']))
##Save user data
data['user'].append(user) data['user'].append(user)
with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt', 'w') as outfile: with open(self.CONFIG_DIRECTORY_LOCATION + '\\config.txt', 'w') as outfile:
json.dump(data, outfile) json.dump(data, outfile)
auth_logger.debug("User saved!") auth_logger.debug("User saved!")
else: else:
auth_logger.debug("User NOT saved! Home directory already exists") auth_logger.debug("User NOT saved! Home directory already exists")

View File

@ -62,7 +62,18 @@ def testUserExists(username: str, password: str):
logging.info('TEST 2 --> User exists with INVALID user :: PASSED') logging.info('TEST 2 --> User exists with INVALID user :: PASSED')
def productionInit():
auth = Authetication()
auth.initConfig()
auth.saveUser('alma','alma')
auth.generatePrivateKeyForUser('alma', 'amla')
auth.saveUser('citrom','citrom')
auth.generatePrivateKeyForUser('citrom', 'mortic')
auth.saveUser('dinnye','dinnye')
auth.generatePrivateKeyForUser('dinnye', 'eynnid')
if __name__ == '__main__': if __name__ == '__main__':
testSaveUser("Diósbejglia", "Diósbejgli") testSaveUser("Diósbejglia", "Diósbejgli")
testAuth("Diósbejglia", "Diósbejgli") testAuth("Diósbejglia", "Diósbejgli")
testUserExists("Diósbejglia", "Diósbejgli") testUserExists("Diósbejglia", "Diósbejgli")
productionInit()