67 lines
1.8 KiB
Python
Executable File
67 lines
1.8 KiB
Python
Executable File
import base64
|
|
import json
|
|
import os
|
|
from typing import Dict
|
|
|
|
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 app.core.config import settings
|
|
|
|
|
|
class CredentialEncryption:
|
|
"""
|
|
Kelas untuk mengenkripsi dan mendekripsi data kredensial.
|
|
|
|
Menggunakan Fernet (implementasi AES-128-CBC) dengan salt dan PBKDF2
|
|
untuk meningkatkan keamanan.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.master_key = settings.SECRET_KEY
|
|
|
|
def _derive_key(self, salt):
|
|
master_key_bytes = self.master_key.encode()
|
|
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=default_backend())
|
|
key = base64.urlsafe_b64encode(kdf.derive(master_key_bytes))
|
|
return key
|
|
|
|
def encrypt(self, data):
|
|
iv = os.urandom(16)
|
|
iv_b64 = base64.b64encode(iv).decode("utf-8")
|
|
|
|
key = self._derive_key(iv)
|
|
|
|
cipher = Fernet(key)
|
|
|
|
data_json = json.dumps(data)
|
|
|
|
encrypted_data = cipher.encrypt(data_json.encode("utf-8"))
|
|
encrypted_b64 = base64.b64encode(encrypted_data).decode("utf-8")
|
|
|
|
return encrypted_b64, iv_b64
|
|
|
|
def decrypt(self, encrypted_data, iv) -> Dict:
|
|
try:
|
|
encrypted_bytes = base64.b64decode(encrypted_data)
|
|
iv_bytes = base64.b64decode(iv)
|
|
|
|
key = self._derive_key(iv_bytes)
|
|
|
|
cipher = Fernet(key)
|
|
|
|
decrypted_data = cipher.decrypt(encrypted_bytes)
|
|
decrypted_str = decrypted_data.decode("utf-8")
|
|
|
|
data = json.loads(decrypted_str)
|
|
|
|
return data
|
|
except Exception as e:
|
|
raise e
|
|
|
|
|
|
# Inisialisasi singleton instance
|
|
credential_encryption = CredentialEncryption()
|