111 lines
2.7 KiB
Python
111 lines
2.7 KiB
Python
import base64
|
|
import os
|
|
import hashlib
|
|
import json
|
|
|
|
from ast import literal_eval
|
|
from getpass import getpass
|
|
from cryptography.fernet import Fernet
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
from ndct.core.paths import KEY_PATH, DB_PATH
|
|
from ndct.core.log import log
|
|
|
|
class Crypt:
|
|
@staticmethod
|
|
def generate_key():
|
|
'''
|
|
Summary:
|
|
Generate a key used for symmetric encryption, using the hash of a user entered password for the salt.
|
|
|
|
Returns:
|
|
Encryption key
|
|
|
|
Encryption type:
|
|
128-bit AES
|
|
'''
|
|
if os.path.isfile(KEY_PATH):
|
|
log("Using existing key '{}' for encryption/decryption".format(KEY_PATH), 'info')
|
|
key = Crypt.get_key()
|
|
|
|
return key
|
|
else:
|
|
log("Attempting to use '{}' but no key found, create a new key or add an existing one".format(KEY_PATH), 'info')
|
|
|
|
password = getpass(prompt='New encryption key password: ')
|
|
password_bytes = password.encode()
|
|
salt = os.urandom(16)
|
|
kdf = PBKDF2HMAC(
|
|
algorithm=hashes.SHA256(),
|
|
length=32,
|
|
salt=salt,
|
|
iterations=100000,
|
|
backend=default_backend()
|
|
)
|
|
key = base64.urlsafe_b64encode(kdf.derive(password_bytes))
|
|
|
|
with open(KEY_PATH, 'wb') as encryption_key:
|
|
encryption_key.write(key)
|
|
|
|
log("Stored encryption key as '{}'".format(KEY_PATH), 'info')
|
|
|
|
return key
|
|
|
|
@staticmethod
|
|
def get_key():
|
|
'''
|
|
Summary:
|
|
Get stored encryption key.
|
|
|
|
Returns:
|
|
Encryption key
|
|
|
|
Encryption type:
|
|
128-bit AES
|
|
'''
|
|
with open(KEY_PATH, 'rb') as encryption_key:
|
|
key = encryption_key.read()
|
|
|
|
return key
|
|
|
|
@staticmethod
|
|
def create_encrypted_file(filename, data):
|
|
'''
|
|
Summary:
|
|
Create an encrypted file from data that is passed to the function.
|
|
|
|
Takes:
|
|
filename: Name of encrypted file
|
|
data: Data to encrypt
|
|
'''
|
|
key = Crypt.generate_key()
|
|
|
|
fernet = Fernet(key)
|
|
encrypted_data = fernet.encrypt(str(data).encode())
|
|
|
|
with open(DB_PATH + filename, 'wb') as encrypted_file:
|
|
encrypted_file.write(encrypted_data)
|
|
|
|
@staticmethod
|
|
def get_encrypted_file_contents(filename):
|
|
'''
|
|
Summary:
|
|
Get the contents of an encrypted file to enable use of the stored data.
|
|
|
|
Takes:
|
|
filename: Name of file to get decrypted contents of
|
|
|
|
Returns:
|
|
Decrypted file contents
|
|
'''
|
|
key = Crypt.generate_key()
|
|
|
|
with open(DB_PATH + filename, 'rb') as encrypted_file:
|
|
data = encrypted_file.read()
|
|
|
|
fernet = Fernet(key)
|
|
temp_data = fernet.decrypt(data).decode()
|
|
temp_data_list = literal_eval(temp_data)
|
|
|
|
return temp_data_list |