""" Browser Fingerprint Entity - Repräsentiert einen kompletten Browser-Fingerprint """ from dataclasses import dataclass, field from datetime import datetime from typing import List, Dict, Any, Optional from enum import Enum import uuid @dataclass class StaticComponents: """Static fingerprint components that don't change""" device_type: str = "desktop" # desktop/mobile/tablet os_family: str = "windows" # windows/macos/linux/android/ios browser_family: str = "chromium" # chromium/firefox/safari gpu_vendor: str = "Intel Inc." gpu_model: str = "Intel Iris OpenGL Engine" cpu_architecture: str = "x86_64" base_fonts: List[str] = field(default_factory=list) base_resolution: tuple = (1920, 1080) base_timezone: str = "Europe/Berlin" def to_dict(self) -> Dict[str, Any]: return { 'device_type': self.device_type, 'os_family': self.os_family, 'browser_family': self.browser_family, 'gpu_vendor': self.gpu_vendor, 'gpu_model': self.gpu_model, 'cpu_architecture': self.cpu_architecture, 'base_fonts': self.base_fonts, 'base_resolution': self.base_resolution, 'base_timezone': self.base_timezone } @dataclass class CanvasNoise: """Canvas Fingerprinting Schutz-Konfiguration""" noise_level: float = 0.02 seed: int = 42 algorithm: str = "gaussian" @dataclass class WebRTCConfig: """WebRTC Konfiguration für IP-Leak Prevention""" enabled: bool = True ice_servers: List[str] = field(default_factory=list) local_ip_mask: str = "10.0.0.x" disable_webrtc: bool = False @dataclass class HardwareConfig: """Hardware-Konfiguration für Fingerprinting""" hardware_concurrency: int = 4 device_memory: int = 8 max_touch_points: int = 0 screen_resolution: tuple = (1920, 1080) color_depth: int = 24 pixel_ratio: float = 1.0 @dataclass class NavigatorProperties: """Navigator-Eigenschaften für Browser-Fingerprint""" platform: str = "Win32" vendor: str = "Google Inc." vendor_sub: str = "" product: str = "Gecko" product_sub: str = "20030107" app_name: str = "Netscape" app_version: str = "5.0" user_agent: str = "" language: str = "de-DE" languages: List[str] = field(default_factory=lambda: ["de-DE", "de", "en-US", "en"]) online: bool = True do_not_track: str = "1" @dataclass class BrowserFingerprint: """Repräsentiert einen kompletten Browser-Fingerprint""" fingerprint_id: str = field(default_factory=lambda: str(uuid.uuid4())) canvas_noise: CanvasNoise = field(default_factory=CanvasNoise) webrtc_config: WebRTCConfig = field(default_factory=WebRTCConfig) font_list: List[str] = field(default_factory=list) hardware_config: HardwareConfig = field(default_factory=HardwareConfig) navigator_props: NavigatorProperties = field(default_factory=NavigatorProperties) created_at: datetime = field(default_factory=datetime.now) last_rotated: datetime = None # WebGL Parameter webgl_vendor: str = "Intel Inc." webgl_renderer: str = "Intel Iris OpenGL Engine" # Audio Context audio_context_base_latency: float = 0.00 audio_context_output_latency: float = 0.00 audio_context_sample_rate: int = 48000 # Timezone timezone: str = "Europe/Berlin" timezone_offset: int = -60 # UTC+1 # Plugins plugins: List[Dict[str, str]] = field(default_factory=list) # New fields for account-bound persistence static_components: Optional[StaticComponents] = None rotation_seed: Optional[str] = None account_bound: bool = False platform_specific_config: Dict[str, Any] = field(default_factory=dict) def to_dict(self) -> Dict[str, Any]: """Konvertiert Fingerprint zu Dictionary für Serialisierung""" return { 'fingerprint_id': self.fingerprint_id, 'canvas_noise': { 'noise_level': self.canvas_noise.noise_level, 'seed': self.canvas_noise.seed, 'algorithm': self.canvas_noise.algorithm }, 'webrtc_config': { 'enabled': self.webrtc_config.enabled, 'ice_servers': self.webrtc_config.ice_servers, 'local_ip_mask': self.webrtc_config.local_ip_mask, 'disable_webrtc': self.webrtc_config.disable_webrtc }, 'font_list': self.font_list, 'hardware_config': { 'hardware_concurrency': self.hardware_config.hardware_concurrency, 'device_memory': self.hardware_config.device_memory, 'max_touch_points': self.hardware_config.max_touch_points, 'screen_resolution': self.hardware_config.screen_resolution, 'color_depth': self.hardware_config.color_depth, 'pixel_ratio': self.hardware_config.pixel_ratio }, 'navigator_props': { 'platform': self.navigator_props.platform, 'vendor': self.navigator_props.vendor, 'vendor_sub': self.navigator_props.vendor_sub, 'product': self.navigator_props.product, 'product_sub': self.navigator_props.product_sub, 'app_name': self.navigator_props.app_name, 'app_version': self.navigator_props.app_version, 'user_agent': self.navigator_props.user_agent, 'language': self.navigator_props.language, 'languages': self.navigator_props.languages, 'online': self.navigator_props.online, 'do_not_track': self.navigator_props.do_not_track }, 'webgl_vendor': self.webgl_vendor, 'webgl_renderer': self.webgl_renderer, 'audio_context': { 'base_latency': self.audio_context_base_latency, 'output_latency': self.audio_context_output_latency, 'sample_rate': self.audio_context_sample_rate }, 'timezone': self.timezone, 'timezone_offset': self.timezone_offset, 'plugins': self.plugins, 'created_at': self.created_at.isoformat(), 'last_rotated': self.last_rotated.isoformat() if self.last_rotated else None, 'static_components': self.static_components.to_dict() if self.static_components else None, 'rotation_seed': self.rotation_seed, 'account_bound': self.account_bound, 'platform_specific_config': self.platform_specific_config } @classmethod def from_dict(cls, data: Dict[str, Any]) -> 'BrowserFingerprint': """Creates BrowserFingerprint from dictionary""" fingerprint = cls() # Basic fields fingerprint.fingerprint_id = data.get('fingerprint_id', str(uuid.uuid4())) fingerprint.webgl_vendor = data.get('webgl_vendor', "Intel Inc.") fingerprint.webgl_renderer = data.get('webgl_renderer', "Intel Iris OpenGL Engine") fingerprint.timezone = data.get('timezone', "Europe/Berlin") fingerprint.timezone_offset = data.get('timezone_offset', -60) fingerprint.plugins = data.get('plugins', []) # Canvas noise if 'canvas_noise' in data: cn = data['canvas_noise'] fingerprint.canvas_noise = CanvasNoise( noise_level=cn.get('noise_level', 0.02), seed=cn.get('seed', 42), algorithm=cn.get('algorithm', 'gaussian') ) # WebRTC config if 'webrtc_config' in data: wc = data['webrtc_config'] fingerprint.webrtc_config = WebRTCConfig( enabled=wc.get('enabled', True), ice_servers=wc.get('ice_servers', []), local_ip_mask=wc.get('local_ip_mask', "10.0.0.x"), disable_webrtc=wc.get('disable_webrtc', False) ) # Hardware config if 'hardware_config' in data: hc = data['hardware_config'] fingerprint.hardware_config = HardwareConfig( hardware_concurrency=hc.get('hardware_concurrency', 4), device_memory=hc.get('device_memory', 8), max_touch_points=hc.get('max_touch_points', 0), screen_resolution=tuple(hc.get('screen_resolution', [1920, 1080])), color_depth=hc.get('color_depth', 24), pixel_ratio=hc.get('pixel_ratio', 1.0) ) # Navigator properties if 'navigator_props' in data: np = data['navigator_props'] fingerprint.navigator_props = NavigatorProperties( platform=np.get('platform', "Win32"), vendor=np.get('vendor', "Google Inc."), vendor_sub=np.get('vendor_sub', ""), product=np.get('product', "Gecko"), product_sub=np.get('product_sub', "20030107"), app_name=np.get('app_name', "Netscape"), app_version=np.get('app_version', "5.0"), user_agent=np.get('user_agent', ""), language=np.get('language', "de-DE"), languages=np.get('languages', ["de-DE", "de", "en-US", "en"]), online=np.get('online', True), do_not_track=np.get('do_not_track', "1") ) # Audio context if 'audio_context' in data: ac = data['audio_context'] fingerprint.audio_context_base_latency = ac.get('base_latency', 0.00) fingerprint.audio_context_output_latency = ac.get('output_latency', 0.00) fingerprint.audio_context_sample_rate = ac.get('sample_rate', 48000) # Font list fingerprint.font_list = data.get('font_list', []) # Dates if 'created_at' in data: fingerprint.created_at = datetime.fromisoformat(data['created_at']) if 'last_rotated' in data and data['last_rotated']: fingerprint.last_rotated = datetime.fromisoformat(data['last_rotated']) # New persistence fields if 'static_components' in data and data['static_components']: sc = data['static_components'] fingerprint.static_components = StaticComponents( device_type=sc.get('device_type', 'desktop'), os_family=sc.get('os_family', 'windows'), browser_family=sc.get('browser_family', 'chromium'), gpu_vendor=sc.get('gpu_vendor', 'Intel Inc.'), gpu_model=sc.get('gpu_model', 'Intel Iris OpenGL Engine'), cpu_architecture=sc.get('cpu_architecture', 'x86_64'), base_fonts=sc.get('base_fonts', []), base_resolution=tuple(sc.get('base_resolution', [1920, 1080])), base_timezone=sc.get('base_timezone', 'Europe/Berlin') ) fingerprint.rotation_seed = data.get('rotation_seed') fingerprint.account_bound = data.get('account_bound', False) fingerprint.platform_specific_config = data.get('platform_specific_config', {}) return fingerprint