import bcrypt import base64 import hashlib import json from cryptography.fernet import Fernet from .models import MasterHash from django.http import JsonResponse # 1. Salva l'hash della master password e la chiave principale cifrata def save_master_data(hashed_password, encrypted_data_key): entry, created = MasterHash.objects.get_or_create(id="1") entry.hash = hashed_password entry.encrypted_data_key = encrypted_data_key entry.save() # 2. Carica i dati della master password def load_master_data(): try: entry = MasterHash.objects.get(id="1") return entry.hash, entry.encrypted_data_key except Exception: return None, None # 3. Autenticazione della master password def authenticate(master_password): stored_hash, encrypted_data_key = load_master_data() if stored_hash is None: hashed_password = bcrypt.hashpw(master_password.encode(), bcrypt.gensalt()) key = Fernet.generate_key() # Genera una chiave principale derived_key = derive_key(master_password) # Deriva la chiave dalla master password encrypted_data_key = encrypt_password(key.decode(), derived_key) # Cifra la chiave principale save_master_data(hashed_password, encrypted_data_key) return True, key # Controlla se la password inserita è corretta if bcrypt.checkpw(master_password.encode(), stored_hash.tobytes()): derived_key = derive_key(master_password) decrypted_data_key = decrypt_password(encrypted_data_key, derived_key) # Decifra la chiave principale return True, decrypted_data_key.encode() return False, None # 4. Funzione per cambiare la master password def change_master_password(old_password, new_password): authenticated, data_key = authenticate(old_password) if not authenticated: return False # Fallisce se la vecchia password non è corretta # Deriviamo la nuova chiave dalla nuova master password new_derived_key = derive_key(new_password) # Cifriamo la chiave principale con la nuova chiave derivata new_encrypted_data_key = encrypt_password(data_key.decode(), new_derived_key) # Creiamo il nuovo hash della nuova master password new_hashed_password = bcrypt.hashpw(new_password.encode(), bcrypt.gensalt()) # Aggiorniamo il database con i nuovi dati save_master_data(new_hashed_password, new_encrypted_data_key) return True # Cambio password riuscito # 5. Deriva una chiave da una password def derive_key(master_password): hash = hashlib.sha256(master_password.encode()).digest() return base64.urlsafe_b64encode(hash) # 6. Cifra una password con una chiave def encrypt_password(password, key): cipher = Fernet(key) return cipher.encrypt(password.encode()).decode() # 7. Decifra una password con una chiave def decrypt_password(encrypted_password, key): cipher = Fernet(key) return cipher.decrypt(encrypted_password.encode()).decode()