hosting-platform/backend/app/utils/encryption.py

118 lines
3.3 KiB
Python
Raw Permalink Normal View History

2026-01-11 14:38:39 +00:00
"""
Encryption/Decryption utilities for sensitive data
Uses Fernet (symmetric encryption) from cryptography library
"""
from cryptography.fernet import Fernet
import os
import base64
from typing import Optional
class EncryptionService:
"""Şifreleme servisi - API token'ları ve hassas verileri şifreler"""
def __init__(self, encryption_key: Optional[str] = None):
"""
Args:
encryption_key: Base64 encoded Fernet key.
Eğer verilmezse ENCRYPTION_KEY env variable kullanılır.
"""
if encryption_key is None:
encryption_key = os.getenv('ENCRYPTION_KEY')
if not encryption_key:
raise ValueError(
"ENCRYPTION_KEY environment variable gerekli! "
"Oluşturmak için: python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())'"
)
# Key'i bytes'a çevir
if isinstance(encryption_key, str):
encryption_key = encryption_key.encode()
self.cipher = Fernet(encryption_key)
def encrypt(self, plaintext: str) -> str:
"""
Metni şifrele
Args:
plaintext: Şifrelenecek metin
Returns:
Base64 encoded şifreli metin
"""
if not plaintext:
return ""
# String'i bytes'a çevir
plaintext_bytes = plaintext.encode('utf-8')
# Şifrele
encrypted_bytes = self.cipher.encrypt(plaintext_bytes)
# Base64 encode et (database'de saklamak için)
return encrypted_bytes.decode('utf-8')
def decrypt(self, encrypted_text: str) -> str:
"""
Şifreli metni çöz
Args:
encrypted_text: Base64 encoded şifreli metin
Returns:
Orijinal metin
"""
if not encrypted_text:
return ""
try:
# Base64 decode et
encrypted_bytes = encrypted_text.encode('utf-8')
# Şifreyi çöz
decrypted_bytes = self.cipher.decrypt(encrypted_bytes)
# Bytes'ı string'e çevir
return decrypted_bytes.decode('utf-8')
except Exception as e:
raise ValueError(f"Şifre çözme hatası: {str(e)}")
@staticmethod
def generate_key() -> str:
"""
Yeni bir encryption key oluştur
Returns:
Base64 encoded Fernet key
"""
return Fernet.generate_key().decode('utf-8')
# Global instance (singleton pattern)
_encryption_service = None
def get_encryption_service() -> EncryptionService:
"""Global encryption service instance'ını al"""
global _encryption_service
if _encryption_service is None:
_encryption_service = EncryptionService()
return _encryption_service
# Convenience functions
def encrypt_text(plaintext: str) -> str:
"""Metni şifrele (convenience function)"""
return get_encryption_service().encrypt(plaintext)
def decrypt_text(encrypted_text: str) -> str:
"""Şifreli metni çöz (convenience function)"""
return get_encryption_service().decrypt(encrypted_text)