Compare commits
3 Commits
4352004ed3
...
ff5b8b4937
Author | SHA1 | Date | |
---|---|---|---|
ff5b8b4937 | |||
aa1b9d7281 | |||
79a2f6e944 |
@ -3,7 +3,7 @@ import mysql.connector
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from flask import jsonify, request
|
from flask import jsonify, request
|
||||||
from ktvmanager.lib.checker import single_account_check
|
from ktvmanager.lib.checker import single_account_check
|
||||||
from ktvmanager.lib.encryption import decrypt_password
|
from ktvmanager.lib.encryption import encrypt_password, decrypt_password
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
@ -42,7 +42,12 @@ def get_user_accounts(user_id):
|
|||||||
query = "SELECT * FROM userAccounts WHERE userID = %s"
|
query = "SELECT * FROM userAccounts WHERE userID = %s"
|
||||||
accounts = _execute_query(query, (user_id,))
|
accounts = _execute_query(query, (user_id,))
|
||||||
for account in accounts:
|
for account in accounts:
|
||||||
account['password'] = decrypt_password(account['password'])
|
try:
|
||||||
|
account['password'] = decrypt_password(account['password'])
|
||||||
|
except Exception as e:
|
||||||
|
# Log the error to the console for debugging
|
||||||
|
print(f"Password decryption failed for account ID {account.get('id', 'N/A')}: {e}")
|
||||||
|
account['password'] = "DECRYPTION_FAILED"
|
||||||
return jsonify(accounts)
|
return jsonify(accounts)
|
||||||
|
|
||||||
def get_stream_names():
|
def get_stream_names():
|
||||||
@ -64,8 +69,9 @@ def single_check():
|
|||||||
|
|
||||||
def add_account():
|
def add_account():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
encrypted_password = encrypt_password(data['password'])
|
||||||
query = "INSERT INTO userAccounts (username, stream, streamURL, expiaryDate, password, userID) VALUES (%s, %s, %s, %s, %s, %s)"
|
query = "INSERT INTO userAccounts (username, stream, streamURL, expiaryDate, password, userID) VALUES (%s, %s, %s, %s, %s, %s)"
|
||||||
params = (data['username'], data['stream'], data['streamURL'], data['expiaryDate'], data['password'], data['userID'])
|
params = (data['username'], data['stream'], data['streamURL'], data['expiaryDate'], encrypted_password, data['userID'])
|
||||||
result = _execute_query(query, params)
|
result = _execute_query(query, params)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
@ -1,17 +1,41 @@
|
|||||||
from pyeasyencrypt.pyeasyencrypt import encrypt_string, decrypt_string
|
|
||||||
import os
|
import os
|
||||||
from dotenv import load_dotenv
|
from Cryptodome.Cipher import AES
|
||||||
|
from Cryptodome.Protocol.KDF import PBKDF2
|
||||||
load_dotenv()
|
from Cryptodome.Random import get_random_bytes
|
||||||
|
|
||||||
|
# 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):
|
def encrypt_password(clear_string):
|
||||||
password = os.getenv("ENCRYPTKEY")
|
"""Encrypts a string using AES-GCM with a derived key."""
|
||||||
encrypted_string = encrypt_string(clear_string, password)
|
salt = get_random_bytes(SALT_SIZE)
|
||||||
return encrypted_string
|
# 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)
|
||||||
|
# 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):
|
def decrypt_password(encrypted_string):
|
||||||
password = os.getenv("ENCRYPTKEY")
|
"""Decrypts a string encrypted with the above function."""
|
||||||
decrypted_string = decrypt_string(encrypted_string, password)
|
data = bytes.fromhex(encrypted_string)
|
||||||
return decrypted_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 + 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)
|
||||||
|
# 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.")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user