77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
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()
|