118 lines
3.3 KiB
Python
118 lines
3.3 KiB
Python
|
|
"""
|
|||
|
|
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)
|
|||
|
|
|