Configuration Key moved into key file

Removed the hard-coded config encryption key and replaced it with a key file that gets generated by ArtNet if not present with a pseudo-random hex using the secret module.

This should improve credential security.
Deletion of the old config files might be necessary.
dev
Peery 2 years ago
parent c6ed71aa93
commit 3374f96bca
Signed by: pandro
SSH Key Fingerprint: SHA256:iBUZSuDxqYr4hYpe9U3BA9NJmXKpbGt4H0S8hUwIbrA

@ -38,7 +38,7 @@ class ArtNetManager:
logging.info("Starting ArtNet client ...") logging.info("Starting ArtNet client ...")
self.known_image_amount = None self.known_image_amount = None
self.config = ConfigReader(config_location, "somePassword") self.config = ConfigReader(config_location)
if self.config.data["version"] != self.config.CONFIG_VERSION: if self.config.data["version"] != self.config.CONFIG_VERSION:
logging.warning("Loaded config version is unequal to expected version! {0} (current) != {1} (expected)" logging.warning("Loaded config version is unequal to expected version! {0} (current) != {1} (expected)"

@ -1,35 +1,42 @@
import os import os
import base64 import base64
import copy import copy
import secrets
import yaml import yaml
from cryptography.exceptions import AlreadyFinalized
from cryptography.exceptions import InvalidTag from cryptography.exceptions import InvalidTag
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
# TODO make the config actually safe, hard-coded encryption password is BAD (but a bit better than plaintext)
class ConfigReader: class ConfigReader:
kdf = None kdf = None
nonce = None nonce = None
CONFIG_VERSION = 3 CONFIG_VERSION = 4
def __init__(self, root_folder: str, password: str): def __init__(self, root_folder: str):
if root_folder is None: if root_folder is None:
raise Exception("No root folder was defined!") raise Exception("No root folder was defined!")
self.__key = None self.__key = None
self.__aesgcm = None self.__aesgcm = None
self.data = {} self.data = {}
self.__password = password
self.__config_location = os.path.join(root_folder, ".artnet", "artnet.config") self.__config_location = os.path.join(root_folder, ".artnet", "artnet.config")
self.__config_key_location = os.path.join(root_folder, ".artnet", "artnet_config.key")
try:
password = self.try_get_config_password()
except FileNotFoundError as e:
if not os.path.exists(self.__config_location):
self.generate_config_key_file()
password = self.try_get_config_password()
else:
raise e
ConfigReader.__create_kdf() ConfigReader.__create_kdf()
self.__key = ConfigReader.kdf.derive(bytes(password.encode('utf-8'))) self.__key = ConfigReader.kdf.derive(bytes(password.encode('utf-8')))
@ -43,6 +50,35 @@ class ConfigReader:
self.create_default_config() self.create_default_config()
self.read_config() self.read_config()
def try_get_config_password(self) -> str:
"""
Attempts to read the config encryption password from the default location
"""
if os.path.exists(self.__config_key_location) and os.path.isfile(self.__config_key_location):
with open(self.__config_key_location, "r") as file:
password = file.readline()
file.close()
return password
else:
raise FileNotFoundError(f"The config encryption key file could not be found! "
f"FileNotFound: {self.__config_key_location}")
def generate_config_key_file(self):
"""
Tries to generate a new pseudo-random generated key file for encrypting the config file.
The key is in plain text and therefore not ideal.
"""
if not os.path.exists(self.__config_key_location) and not os.path.exists(self.__config_location):
with open(self.__config_key_location, "w") as file:
file.write(secrets.token_hex(100))
file.close()
else:
raise Exception("Something went terribly wrong! "
"Tried to create new config key file although the key file or config file aready exists! "
"Perhaps old config?")
def update_config(self): def update_config(self):
""" """
Update the written config with the local settings Update the written config with the local settings

Loading…
Cancel
Save