diff --git a/ktvmanager/lib/encryption.py b/ktvmanager/lib/encryption.py index 521ce63..500bba2 100644 --- a/ktvmanager/lib/encryption.py +++ b/ktvmanager/lib/encryption.py @@ -1,26 +1,41 @@ import os -from Crypto.Cipher import AES -from Crypto.Protocol.KDF import PBKDF2 -from Crypto.Random import get_random_bytes +from Cryptodome.Cipher import AES +from Cryptodome.Protocol.KDF import PBKDF2 +from Cryptodome.Random import get_random_bytes -SECRET = "BBLBTV-DNS-PASSWORDS" +# Use a new secret for the new encryption scheme +SECRET = "KTVM-NEW-ENCRYPTION-SECRET" SALT_SIZE = 16 KEY_SIZE = 32 ITERATIONS = 100000 +AUTH_TAG_LENGTH = 16 def encrypt_password(clear_string): + """Encrypts a string using AES-GCM with a derived key.""" salt = get_random_bytes(SALT_SIZE) + # Derive a key from the master secret and a random salt key = PBKDF2(SECRET, salt, dkLen=KEY_SIZE, count=ITERATIONS) cipher = AES.new(key, AES.MODE_GCM) - ciphertext, tag = cipher.encrypt_and_digest(clear_string.encode()) + # Encrypt the data + ciphertext, tag = cipher.encrypt_and_digest(clear_string.encode('utf-8')) + # Return a single hex-encoded string containing all parts return (salt + cipher.nonce + tag + ciphertext).hex() def decrypt_password(encrypted_string): + """Decrypts a string encrypted with the above function.""" data = bytes.fromhex(encrypted_string) + # Extract the components from the encrypted string salt = data[:SALT_SIZE] nonce = data[SALT_SIZE:SALT_SIZE + 16] - tag = data[SALT_SIZE + 16:SALT_SIZE + 32] - ciphertext = data[SALT_SIZE + 32:] + tag = data[SALT_SIZE + 16:SALT_SIZE + 16 + AUTH_TAG_LENGTH] + ciphertext = data[SALT_SIZE + 16 + AUTH_TAG_LENGTH:] + # Re-derive the same key using the stored salt key = PBKDF2(SECRET, salt, dkLen=KEY_SIZE, count=ITERATIONS) cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) - return cipher.decrypt_and_verify(ciphertext, tag).decode() + # Decrypt and verify the data + try: + decrypted_bytes = cipher.decrypt_and_verify(ciphertext, tag) + return decrypted_bytes.decode('utf-8') + except ValueError: + # This will be raised if the MAC check fails (tampered data or wrong key) + raise ValueError("Decryption failed: MAC check failed. The data may be corrupt or the key is incorrect.")