304 Zeilen
10 KiB
Python
304 Zeilen
10 KiB
Python
"""
|
|
Lizenzvalidator - Validiert Lizenzschlüssel und enthält Sicherheitsalgorithmen
|
|
"""
|
|
|
|
import os
|
|
import logging
|
|
import hashlib
|
|
import hmac
|
|
import base64
|
|
import json
|
|
import time
|
|
import random
|
|
import string
|
|
from datetime import datetime, timedelta
|
|
from typing import Dict, Optional, Tuple, Any, List
|
|
|
|
# Konfiguriere Logger
|
|
logger = logging.getLogger("license_validator")
|
|
|
|
class LicenseValidator:
|
|
"""
|
|
Validiert Lizenzschlüssel und führt kryptografische Operationen durch.
|
|
Enthält Platzhaltercode für die Lizenzvalidierung.
|
|
"""
|
|
|
|
# Sicherheitsschlüssel (würde in einer echten Implementierung nicht im Code stehen)
|
|
SECRET_KEY = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
|
|
|
|
def __init__(self):
|
|
"""Initialisiert den LicenseValidator."""
|
|
logger.info("Lizenzvalidator initialisiert")
|
|
|
|
def validate_key_format(self, license_key: str) -> bool:
|
|
"""
|
|
Prüft, ob der Lizenzschlüssel das richtige Format hat.
|
|
|
|
Args:
|
|
license_key: Der zu prüfende Lizenzschlüssel
|
|
|
|
Returns:
|
|
bool: True, wenn das Format gültig ist, False sonst
|
|
"""
|
|
# Einfacher Formatcheck für XXXXX-XXXXX-XXXXX-XXXXX
|
|
import re
|
|
return bool(re.match(r'^[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}$', license_key))
|
|
|
|
def validate_key_checksum(self, license_key: str) -> bool:
|
|
"""
|
|
Prüft, ob die Prüfsumme des Lizenzschlüssels gültig ist.
|
|
|
|
Args:
|
|
license_key: Der zu prüfende Lizenzschlüssel
|
|
|
|
Returns:
|
|
bool: True, wenn die Prüfsumme gültig ist, False sonst
|
|
"""
|
|
# Platzhalterimplementierung - in einer echten Implementierung würde hier
|
|
# eine Prüfsummenberechnung stehen
|
|
|
|
# Entferne Bindestriche für die Verarbeitung
|
|
key_parts = license_key.split('-')
|
|
if len(key_parts) != 4:
|
|
return False
|
|
|
|
# Einfacher Check: Letzter Buchstabe des ersten Teils ist abhängig von den ersten Buchstaben
|
|
# der anderen Teile (XOR der ASCII-Werte)
|
|
try:
|
|
check_char = key_parts[0][-1]
|
|
calculated_char = chr(ord(key_parts[1][0]) ^ ord(key_parts[2][0]) ^ ord(key_parts[3][0]))
|
|
|
|
# In einer echten Implementierung wäre diese Prüfung viel stärker
|
|
return check_char == calculated_char
|
|
except IndexError:
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Fehler bei der Prüfsummenberechnung: {e}")
|
|
return False
|
|
|
|
def decrypt_license_data(self, license_key: str) -> Optional[Dict[str, Any]]:
|
|
"""
|
|
Entschlüsselt Lizenzinformationen aus dem Schlüssel.
|
|
|
|
Args:
|
|
license_key: Der zu entschlüsselnde Lizenzschlüssel
|
|
|
|
Returns:
|
|
Optional[Dict[str, Any]]: Entschlüsselte Lizenzdaten oder None bei Fehler
|
|
"""
|
|
# Platzhalterimplementierung - in einer echten Implementierung würde hier
|
|
# eine Entschlüsselung stehen
|
|
|
|
if not self.validate_key_format(license_key):
|
|
return None
|
|
|
|
# Mock-Daten generieren
|
|
key_parts = license_key.split('-')
|
|
|
|
# Aus dem Schlüssel Informationen "ableiten"
|
|
try:
|
|
# Verwende den ersten Teil für die Lizenzart
|
|
license_type_index = sum(ord(c) for c in key_parts[0]) % 3
|
|
license_types = ["basic", "premium", "enterprise"]
|
|
license_type = license_types[license_type_index]
|
|
|
|
# Verwende den zweiten Teil für die Gültigkeitsdauer
|
|
validity_months = (sum(ord(c) for c in key_parts[1]) % 12) + 1
|
|
|
|
# Verwende den dritten Teil für die Funktionen
|
|
features_count = (sum(ord(c) for c in key_parts[2]) % 5) + 1
|
|
all_features = ["multi_account", "proxy_rotation", "advanced_analytics",
|
|
"sms_verification", "captcha_solving", "phone_verification",
|
|
"export", "scheduling"]
|
|
features = all_features[:features_count]
|
|
|
|
# Generiere ein "verschlüsseltes" Token
|
|
token = hashlib.sha256(license_key.encode()).hexdigest()
|
|
|
|
# Aktuelle Zeit für Aktivierung
|
|
now = datetime.now()
|
|
activation_date = now.strftime("%Y-%m-%d %H:%M:%S")
|
|
expiry_date = (now + timedelta(days=30*validity_months)).strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
# Lizenzdaten zusammenstellen
|
|
license_data = {
|
|
"license_type": license_type,
|
|
"features": features,
|
|
"activation_date": activation_date,
|
|
"expiry_date": expiry_date,
|
|
"token": token
|
|
}
|
|
|
|
return license_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler bei der Entschlüsselung des Lizenzschlüssels: {e}")
|
|
return None
|
|
|
|
def generate_license_key(self, license_type: str = "basic", validity_months: int = 12,
|
|
features: List[str] = None) -> str:
|
|
"""
|
|
Generiert einen Lizenzschlüssel.
|
|
|
|
Args:
|
|
license_type: Art der Lizenz ("basic", "premium", "enterprise")
|
|
validity_months: Gültigkeitsdauer in Monaten
|
|
features: Liste der Funktionen
|
|
|
|
Returns:
|
|
str: Generierter Lizenzschlüssel
|
|
"""
|
|
# Platzhalterimplementierung - in einer echten Implementierung würde hier
|
|
# eine sichere Schlüsselgenerierung stehen
|
|
|
|
# Verwende die Eingabeparameter als Seed für die Generierung
|
|
seed = f"{license_type}{validity_months}{','.join(features or [])}{time.time()}"
|
|
random.seed(hashlib.md5(seed.encode()).hexdigest())
|
|
|
|
# Generiere 4 Teile mit jeweils 5 Zeichen (Großbuchstaben und Zahlen)
|
|
chars = string.ascii_uppercase + string.digits
|
|
parts = []
|
|
|
|
for _ in range(4):
|
|
part = ''.join(random.choice(chars) for _ in range(5))
|
|
parts.append(part)
|
|
|
|
# Stelle sicher, dass der letzte Buchstabe des ersten Teils
|
|
# ein XOR der ersten Buchstaben der anderen Teile ist
|
|
# (für die einfache Prüfsumme)
|
|
calc_char = chr(ord(parts[1][0]) ^ ord(parts[2][0]) ^ ord(parts[3][0]))
|
|
parts[0] = parts[0][:-1] + calc_char
|
|
|
|
# Verbinde die Teile mit Bindestrichen
|
|
license_key = '-'.join(parts)
|
|
|
|
return license_key
|
|
|
|
def sign_data(self, data: str) -> str:
|
|
"""
|
|
Signiert Daten mit dem geheimen Schlüssel.
|
|
|
|
Args:
|
|
data: Zu signierende Daten
|
|
|
|
Returns:
|
|
str: Signatur
|
|
"""
|
|
return hmac.new(
|
|
self.SECRET_KEY.encode(),
|
|
data.encode(),
|
|
hashlib.sha256
|
|
).hexdigest()
|
|
|
|
def verify_signature(self, data: str, signature: str) -> bool:
|
|
"""
|
|
Überprüft die Signatur von Daten.
|
|
|
|
Args:
|
|
data: Signierte Daten
|
|
signature: Zu überprüfende Signatur
|
|
|
|
Returns:
|
|
bool: True, wenn die Signatur gültig ist, False sonst
|
|
"""
|
|
expected_signature = self.sign_data(data)
|
|
return hmac.compare_digest(expected_signature, signature)
|
|
|
|
def encode_license_data(self, data: Dict[str, Any]) -> str:
|
|
"""
|
|
Kodiert Lizenzdaten zur sicheren Übertragung.
|
|
|
|
Args:
|
|
data: Zu kodierende Lizenzdaten
|
|
|
|
Returns:
|
|
str: Kodierte Lizenzdaten
|
|
"""
|
|
# Daten in JSON konvertieren
|
|
json_data = json.dumps(data, sort_keys=True)
|
|
|
|
# Signatur hinzufügen
|
|
signature = self.sign_data(json_data)
|
|
|
|
# Zusammen mit der Signatur kodieren
|
|
combined = f"{json_data}|{signature}"
|
|
encoded = base64.b64encode(combined.encode()).decode()
|
|
|
|
return encoded
|
|
|
|
def decode_license_data(self, encoded: str) -> Optional[Dict[str, Any]]:
|
|
"""
|
|
Dekodiert und überprüft kodierte Lizenzdaten.
|
|
|
|
Args:
|
|
encoded: Kodierte Lizenzdaten
|
|
|
|
Returns:
|
|
Optional[Dict[str, Any]]: Dekodierte Lizenzdaten oder None bei Fehler
|
|
"""
|
|
try:
|
|
# Dekodieren
|
|
decoded = base64.b64decode(encoded).decode()
|
|
|
|
# In Daten und Signatur aufteilen
|
|
json_data, signature = decoded.split('|', 1)
|
|
|
|
# Signatur überprüfen
|
|
if not self.verify_signature(json_data, signature):
|
|
logger.warning("Ungültige Signatur in lizenzierten Daten")
|
|
return None
|
|
|
|
# JSON parsen
|
|
data = json.loads(json_data)
|
|
|
|
return data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Dekodieren der Lizenzdaten: {e}")
|
|
return None
|
|
|
|
|
|
# Beispielnutzung, wenn direkt ausgeführt
|
|
if __name__ == "__main__":
|
|
# Konfiguriere Logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
|
|
# Beispiel für LicenseValidator
|
|
validator = LicenseValidator()
|
|
|
|
# Generiere einen Lizenzschlüssel
|
|
features = ["multi_account", "proxy_rotation", "advanced_analytics"]
|
|
key = validator.generate_license_key("premium", 12, features)
|
|
print(f"Generierter Lizenzschlüssel: {key}")
|
|
|
|
# Validiere den Schlüssel
|
|
is_valid_format = validator.validate_key_format(key)
|
|
is_valid_checksum = validator.validate_key_checksum(key)
|
|
print(f"Format gültig: {is_valid_format}")
|
|
print(f"Prüfsumme gültig: {is_valid_checksum}")
|
|
|
|
# Entschlüssele Lizenzdaten
|
|
license_data = validator.decrypt_license_data(key)
|
|
if license_data:
|
|
print("\nEntschlüsselte Lizenzdaten:")
|
|
for k, v in license_data.items():
|
|
print(f" {k}: {v}")
|
|
|
|
# Beispiel für Kodierung und Dekodierung
|
|
test_data = {
|
|
"name": "Test License",
|
|
"type": "premium",
|
|
"expires": "2026-01-01"
|
|
}
|
|
|
|
encoded = validator.encode_license_data(test_data)
|
|
print(f"\nKodierte Daten: {encoded}")
|
|
|
|
decoded = validator.decode_license_data(encoded)
|
|
if decoded:
|
|
print("\nDekodierte Daten:")
|
|
for k, v in decoded.items():
|
|
print(f" {k}: {v}") |