Files
AccountForger-neuerUpload/licensing/hardware_fingerprint.py
Claude Project Manager 04585e95b6 Initial commit
2025-08-01 23:50:28 +02:00

312 Zeilen
10 KiB
Python
Originalformat Blame Verlauf

"""
Hardware Fingerprint Generator fuer die Lizenzierung.
Erstellt einen eindeutigen Hardware-Hash basierend auf System-Eigenschaften.
"""
import hashlib
import platform
import socket
import uuid
import os
import subprocess
import logging
from typing import List, Optional
logger = logging.getLogger("hardware_fingerprint")
class HardwareFingerprint:
"""Generiert und verwaltet Hardware-Fingerprints f<>r die Lizenzierung."""
FINGERPRINT_FILE = os.path.join("config", ".hardware_id")
def __init__(self):
"""Initialisiert den Fingerprint-Generator."""
os.makedirs("config", exist_ok=True)
def get_mac_address(self) -> Optional[str]:
"""
Holt die MAC-Adresse der prim<69>ren Netzwerkkarte.
Returns:
MAC-Adresse als String oder None
"""
try:
# UUID-basierte MAC-Adresse (funktioniert cross-platform)
mac = ':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)
for ele in range(0,8*6,8)][::-1])
if mac != "00:00:00:00:00:00":
return mac
except Exception as e:
logger.warning(f"Fehler beim Abrufen der MAC-Adresse: {e}")
return None
def get_cpu_info(self) -> str:
"""
Holt CPU-Informationen.
Returns:
CPU-Info als String
"""
try:
# Platform-unabh<62>ngige CPU-Info
cpu_info = platform.processor()
if not cpu_info:
cpu_info = platform.machine()
return cpu_info or "unknown"
except Exception as e:
logger.warning(f"Fehler beim Abrufen der CPU-Info: {e}")
return "unknown"
def get_system_uuid(self) -> Optional[str]:
"""
Versucht die System-UUID zu ermitteln.
Returns:
System-UUID als String oder None
"""
try:
# Windows
if platform.system() == "Windows":
try:
output = subprocess.check_output(
"wmic csproduct get UUID",
shell=True,
stderr=subprocess.DEVNULL
).decode()
lines = output.strip().split('\n')
if len(lines) > 1:
uuid_str = lines[1].strip()
if uuid_str and uuid_str != "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF":
return uuid_str
except:
pass
# Linux
elif platform.system() == "Linux":
try:
with open("/sys/class/dmi/id/product_uuid", "r") as f:
uuid_str = f.read().strip()
if uuid_str:
return uuid_str
except:
pass
# Alternative f<>r Linux
try:
with open("/etc/machine-id", "r") as f:
return f.read().strip()
except:
pass
# macOS
elif platform.system() == "Darwin":
try:
output = subprocess.check_output(
["ioreg", "-rd1", "-c", "IOPlatformExpertDevice"],
stderr=subprocess.DEVNULL
).decode()
for line in output.split('\n'):
if 'IOPlatformUUID' in line:
uuid_str = line.split('"')[-2]
if uuid_str:
return uuid_str
except:
pass
except Exception as e:
logger.warning(f"Fehler beim Abrufen der System-UUID: {e}")
return None
def get_disk_serial(self) -> Optional[str]:
"""
Versucht die Seriennummer der Systemfestplatte zu ermitteln.
Returns:
Disk Serial als String oder None
"""
try:
if platform.system() == "Windows":
try:
output = subprocess.check_output(
"wmic diskdrive get serialnumber",
shell=True,
stderr=subprocess.DEVNULL
).decode()
lines = output.strip().split('\n')
for line in lines[1:]:
serial = line.strip()
if serial and serial != "SerialNumber":
return serial
except:
pass
elif platform.system() == "Linux":
try:
# Versuche verschiedene Methoden
for device in ["/dev/sda", "/dev/nvme0n1", "/dev/vda"]:
if os.path.exists(device):
try:
output = subprocess.check_output(
["sudo", "hdparm", "-I", device],
stderr=subprocess.DEVNULL
).decode()
for line in output.split('\n'):
if 'Serial Number:' in line:
return line.split(':')[1].strip()
except:
pass
except:
pass
except Exception as e:
logger.warning(f"Fehler beim Abrufen der Disk-Serial: {e}")
return None
def generate_hardware_hash(self) -> str:
"""
Generiert einen eindeutigen Hardware-Hash basierend auf verschiedenen
System-Eigenschaften.
Returns:
Hardware-Hash als String
"""
components = []
# 1. Hostname (immer verf<72>gbar)
hostname = socket.gethostname()
components.append(f"HOST:{hostname}")
# 2. MAC-Adresse
mac = self.get_mac_address()
if mac:
components.append(f"MAC:{mac}")
# 3. CPU-Info
cpu = self.get_cpu_info()
components.append(f"CPU:{cpu}")
# 4. System-UUID
sys_uuid = self.get_system_uuid()
if sys_uuid:
components.append(f"UUID:{sys_uuid}")
# 5. Disk Serial
disk_serial = self.get_disk_serial()
if disk_serial:
components.append(f"DISK:{disk_serial}")
# 6. Platform-Info
components.append(f"PLATFORM:{platform.system()}-{platform.machine()}")
# 7. Username (als Fallback)
try:
username = os.getlogin()
components.append(f"USER:{username}")
except:
pass
# Kombiniere alle Komponenten
fingerprint_data = "|".join(sorted(components))
# Erstelle SHA256 Hash
hash_object = hashlib.sha256(fingerprint_data.encode())
hardware_hash = hash_object.hexdigest()
logger.info(f"Hardware-Fingerprint generiert mit {len(components)} Komponenten")
logger.debug(f"Komponenten: {components}")
return hardware_hash
def get_or_create_fingerprint(self) -> str:
"""
Holt den gespeicherten Fingerprint oder erstellt einen neuen.
Returns:
Hardware-Fingerprint als String
"""
# Pr<50>fe ob bereits ein Fingerprint existiert
if os.path.exists(self.FINGERPRINT_FILE):
try:
with open(self.FINGERPRINT_FILE, 'r') as f:
stored_hash = f.read().strip()
if stored_hash:
logger.info("Gespeicherten Hardware-Fingerprint gefunden")
return stored_hash
except Exception as e:
logger.warning(f"Fehler beim Lesen des gespeicherten Fingerprints: {e}")
# Generiere neuen Fingerprint
hardware_hash = self.generate_hardware_hash()
# Speichere f<>r zuk<75>nftige Verwendung
try:
with open(self.FINGERPRINT_FILE, 'w') as f:
f.write(hardware_hash)
logger.info("Hardware-Fingerprint gespeichert")
except Exception as e:
logger.error(f"Fehler beim Speichern des Fingerprints: {e}")
return hardware_hash
def get_machine_name(self) -> str:
"""
Gibt den Maschinennamen zur<75>ck.
Returns:
Maschinenname
"""
try:
return socket.gethostname()
except:
return "Unknown-PC"
def get_system_info(self) -> dict:
"""
Sammelt detaillierte System-Informationen.
Returns:
Dictionary mit System-Infos
"""
return {
"hostname": self.get_machine_name(),
"platform": platform.system(),
"platform_release": platform.release(),
"platform_version": platform.version(),
"architecture": platform.machine(),
"processor": self.get_cpu_info(),
"python_version": platform.python_version(),
"mac_address": self.get_mac_address(),
"system_uuid": self.get_system_uuid()
}
# Test-Funktion
if __name__ == "__main__":
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
print("=== Hardware Fingerprint Test ===\n")
fingerprint = HardwareFingerprint()
# System-Info anzeigen
print("System-Informationen:")
info = fingerprint.get_system_info()
for key, value in info.items():
print(f" {key}: {value}")
# Fingerprint generieren
print("\nHardware-Fingerprint:")
hw_hash = fingerprint.get_or_create_fingerprint()
print(f" Hash: {hw_hash}")
print(f" L<>nge: {len(hw_hash)} Zeichen")
# Maschinenname
print(f"\nMaschinenname: {fingerprint.get_machine_name()}")
print("\n=== Test abgeschlossen ===")