# Cryptography Module - Sicherheitsrichtlinien Detaillierte Sicherheitsrichtlinien und Best Practices für das Cryptography Module. ## Grundlegende Sicherheitsprinzipien ### Defense in Depth Das Cryptography Module implementiert mehrschichtigen Schutz: 1. **Algorithmus-Ebene**: Moderne, peer-reviewed Algorithmen (Argon2ID, SHA-3, ECDSA) 2. **Implementation-Ebene**: Timing-sichere Operationen und sichere Speicherverwaltung 3. **Application-Ebene**: Sichere Integration und Konfiguration 4. **System-Ebene**: Sicherer Random Number Generator und Entropie-Validierung ### Zero-Trust Architektur ```php // ✅ Vertraue niemals Eingaben - validiere alles final readonly class SecureTokenValidator { public function validateApiKey(string $providedKey): ?ApiKeyContext { // Eingabe-Validierung if (empty($providedKey) || strlen($providedKey) < 32) { return null; } // Format-Validierung if (!$this->tokenGenerator->isValidFormat($providedKey, 'base64_url')) { return null; } // Timing-sicherer Vergleich mit gespeichertem Hash $keyHash = hash('sha256', $providedKey); $storedKey = $this->repository->findByHash($keyHash); if (!$storedKey || !hash_equals($keyHash, $storedKey->getHash())) { return null; } // Zusätzliche Sicherheitsprüfungen return $this->performSecurityChecks($storedKey); } } ``` ## Kryptographische Best Practices ### Sichere Schlüssel-Ableitung ```php // ✅ Empfohlene Parameter für verschiedene Szenarien final readonly class SecureKeyDerivation { private const SECURITY_LEVELS = [ // Hohe Sicherheit für sensitive Daten 'high_security' => [ 'algorithm' => 'argon2id', 'memory_cost' => 131072, // 128 MB 'time_cost' => 6, // 6 Iterationen 'threads' => 4, // 4 Threads 'key_length' => 32 // 256 Bit ], // Standard für normale Anwendungen 'standard' => [ 'algorithm' => 'argon2id', 'memory_cost' => 65536, // 64 MB 'time_cost' => 4, // 4 Iterationen 'threads' => 3, // 3 Threads 'key_length' => 32 // 256 Bit ], // Kompatibilität mit älteren Systemen 'legacy_compatible' => [ 'algorithm' => 'pbkdf2-sha256', 'iterations' => 200000, // 200k Iterationen 'key_length' => 32 // 256 Bit ] ]; public function hashPassword(string $password, string $level = 'standard'): DerivedKey { $params = self::SECURITY_LEVELS[$level] ?? self::SECURITY_LEVELS['standard']; return match ($params['algorithm']) { 'argon2id' => $this->kdf->argon2id( $password, $this->kdf->generateSalt(32), $params['memory_cost'], $params['time_cost'], $params['threads'], $params['key_length'] ), 'pbkdf2-sha256' => $this->kdf->pbkdf2( $password, $this->kdf->generateSalt(32), $params['iterations'], $params['key_length'] ) }; } } ``` ### Sichere Token-Generierung ```php // ✅ Token-Sicherheit nach Verwendungszweck final readonly class SecurityAwareTokenGenerator { private const TOKEN_SECURITY_REQUIREMENTS = [ 'api_key' => [ 'length' => 32, // 256 Bit 'format' => 'base64_url', 'entropy_min' => 7.0, 'expires' => false, // Langlebig 'single_use' => false ], 'session' => [ 'length' => 48, // 384 Bit (höhere Sicherheit) 'format' => 'base64_url', 'entropy_min' => 7.5, 'expires' => true, 'single_use' => false ], 'csrf' => [ 'length' => 32, // 256 Bit 'format' => 'base64_url', 'entropy_min' => 7.0, 'expires' => true, // Kurze Lebensdauer 'single_use' => true // Einmalverwendung ], 'password_reset' => [ 'length' => 64, // 512 Bit (maximale Sicherheit) 'format' => 'base64_url', 'entropy_min' => 7.8, 'expires' => true, 'single_use' => true, 'max_lifetime' => 3600 * 2 // 2 Stunden ] ]; public function generateSecureToken(string $type): SecureToken { $requirements = self::TOKEN_SECURITY_REQUIREMENTS[$type] ?? throw new InvalidArgumentException("Unknown token type: {$type}"); do { $token = $this->tokenGenerator->generate( $type, $requirements['length'], $requirements['format'] ); // Entropie validieren $entropy = $this->utils->calculateShannonEntropy($token->getRawBytes()); } while ($entropy < $requirements['entropy_min']); return $token; } } ``` ## Timing-Attack Prevention ### Konstante Ausführungszeit ```php // ✅ Timing-sichere Implementierung final readonly class TimingSafeOperations { public function authenticateUser(string $email, string $password): ?User { $user = $this->userRepository->findByEmail(new Email($email)); // WICHTIG: Immer Hashing durchführen, auch bei ungültigem User $providedHash = $user ? $user->getPasswordHash() : $this->createDummyHash(); // Konstante Ausführungszeit $isValid = $this->kdf->verify($password, $providedHash); // Zusätzliche konstante Verzögerung $this->enforceConstantTime(); return $isValid && $user ? $user : null; } private function createDummyHash(): DerivedKey { // Dummy-Hash mit gleichen Parametern wie echte Hashes static $dummyHash = null; if ($dummyHash === null) { $dummyHash = $this->kdf->hashPassword('dummy-password', 'argon2id'); } return $dummyHash; } private function enforceConstantTime(): void { // Minimale zusätzliche Verzögerung (1-5ms) usleep(random_int(1000, 5000)); } } ``` ### Side-Channel Resistance ```php // ✅ Schutz vor Side-Channel-Angriffen final readonly class SideChannelResistantComparison { public function compareSecrets(string $secret1, string $secret2): bool { // PHP's hash_equals ist timing-sicher implementiert return hash_equals($secret1, $secret2); } public function compareArrays(array $array1, array $array2): bool { // Arrays zu Strings serialisieren für timing-sicheren Vergleich $string1 = json_encode($array1, JSON_SORT_KEYS); $string2 = json_encode($array2, JSON_SORT_KEYS); return hash_equals($string1, $string2); } public function searchInArray(array $haystack, mixed $needle): bool { $found = false; // Alle Elemente durchgehen (konstante Zeit) foreach ($haystack as $value) { $isMatch = is_string($value) && is_string($needle) ? hash_equals($value, $needle) : ($value === $needle); $found = $found || $isMatch; // Kein frühes Beenden } return $found; } } ``` ## Sichere Speicherverwaltung ### Sensitive Data Handling ```php // ✅ Sicherer Umgang mit sensitiven Daten final readonly class SecureMemoryManagement { public function processSecretData(string $secretData): ProcessedResult { try { // Daten verarbeiten $result = $this->doSecretProcessing($secretData); // Sensitive Daten aus Speicher löschen $this->utils->secureWipe($secretData); return $result; } catch (Throwable $e) { // Auch bei Fehlern Speicher löschen $this->utils->secureWipe($secretData); throw $e; } } public function createSecureTemporaryFile(string $data): SecureTemporaryFile { // Temporary file mit restriktiven Berechtigungen erstellen $tempFile = tempnam(sys_get_temp_dir(), 'secure_'); chmod($tempFile, 0600); // Nur Owner kann lesen/schreiben // Daten schreiben und sofort aus Speicher löschen file_put_contents($tempFile, $data); $this->utils->secureWipe($data); // Auto-cleanup mit Destruktor return new SecureTemporaryFile($tempFile); } } // Auto-cleanup für temporäre Dateien final class SecureTemporaryFile { public function __construct(private string $filePath) {} public function __destruct() { if (file_exists($this->filePath)) { // Datei mehrfach überschreiben vor dem Löschen $fileSize = filesize($this->filePath); for ($i = 0; $i < 3; $i++) { file_put_contents($this->filePath, random_bytes($fileSize)); } unlink($this->filePath); } } public function getPath(): string { return $this->filePath; } } ``` ## Input Validation und Sanitization ### Comprehensive Input Validation ```php // ✅ Umfassende Eingabe-Validierung final readonly class CryptographicInputValidator { public function validatePasswordStrength(string $password): ValidationResult { $errors = []; // Länge prüfen if (strlen($password) < 8) { $errors[] = 'Password must be at least 8 characters long'; } // Komplexität prüfen if (!preg_match('/[A-Z]/', $password)) { $errors[] = 'Password must contain uppercase letters'; } if (!preg_match('/[a-z]/', $password)) { $errors[] = 'Password must contain lowercase letters'; } if (!preg_match('/[0-9]/', $password)) { $errors[] = 'Password must contain numbers'; } if (!preg_match('/[^A-Za-z0-9]/', $password)) { $errors[] = 'Password must contain special characters'; } // Entropie prüfen $entropy = $this->utils->calculateShannonEntropy($password); if ($entropy < 3.5) { $errors[] = 'Password has insufficient entropy'; } // Gegen Common-Passwords prüfen if ($this->isCommonPassword($password)) { $errors[] = 'Password is too common'; } return new ValidationResult(empty($errors), $errors); } public function validateApiKeyFormat(string $apiKey): bool { // Länge prüfen (32-64 Zeichen) if (strlen($apiKey) < 32 || strlen($apiKey) > 64) { return false; } // Format prüfen (Base64URL) if (!preg_match('/^[A-Za-z0-9_-]+$/', $apiKey)) { return false; } // Entropie validieren $entropy = $this->utils->calculateShannonEntropy($apiKey); return $entropy >= 6.0; } public function sanitizeUserInput(string $input): string { // Whitespace normalisieren $sanitized = trim($input); // Null-Bytes entfernen (verhindern Directory Traversal) $sanitized = str_replace("\0", '', $sanitized); // Control Characters entfernen $sanitized = preg_replace('/[\x00-\x1F\x7F]/', '', $sanitized); return $sanitized; } private function isCommonPassword(string $password): bool { $commonPasswords = [ 'password', '123456', 'password123', 'admin', 'qwerty', 'letmein', 'welcome', 'monkey', '1234567890', 'password1' ]; $lowercase = strtolower($password); foreach ($commonPasswords as $common) { if ($lowercase === $common || levenshtein($lowercase, $common) <= 2) { return true; } } return false; } } ``` ## Rate Limiting und Abuse Prevention ### Cryptographic Rate Limiting ```php // ✅ Rate-Limiting für kryptographische Operationen final readonly class CryptographicRateLimiter { private const LIMITS = [ 'password_attempts' => ['count' => 5, 'window' => 900], // 5 in 15 Min 'token_generation' => ['count' => 100, 'window' => 3600], // 100 in 1 Stunde 'password_reset' => ['count' => 3, 'window' => 3600], // 3 in 1 Stunde 'otp_generation' => ['count' => 5, 'window' => 300], // 5 in 5 Min ]; public function __construct( private CacheInterface $cache, private SecurityEventLogger $securityLogger ) {} public function checkLimit(string $operation, string $identifier): bool { $limit = self::LIMITS[$operation] ?? null; if (!$limit) { return true; // Kein Limit definiert } $cacheKey = "ratelimit_{$operation}_{$identifier}"; $attempts = $this->cache->get($cacheKey, []); $now = time(); // Abgelaufene Versuche entfernen $attempts = array_filter($attempts, fn($timestamp) => $now - $timestamp < $limit['window']); if (count($attempts) >= $limit['count']) { // Rate-Limit erreicht $this->securityLogger->logRateLimitExceeded($operation, $identifier); return false; } // Neuen Versuch hinzufügen $attempts[] = $now; $this->cache->set($cacheKey, $attempts, $limit['window']); return true; } public function recordFailedAttempt(string $operation, string $identifier): void { $cacheKey = "failed_{$operation}_{$identifier}"; $failures = $this->cache->get($cacheKey, 0); $failures++; $this->cache->set($cacheKey, $failures, 3600); // 1 Stunde // Bei vielen Fehlversuchen Sicherheitsteam benachrichtigen if ($failures >= 10) { $this->securityLogger->logSuspiciousActivity( $operation, $identifier, "Multiple failed attempts: {$failures}" ); } } } ``` ## Error Handling und Information Leakage Prevention ### Secure Error Handling ```php // ✅ Sichere Fehlerbehandlung ohne Information Leakage final readonly class SecureErrorHandler { public function handleCryptographicError(Throwable $error): ErrorResponse { // Detaillierte Logs für interne Analyse $this->logger->error('Cryptographic error occurred', [ 'error_type' => get_class($error), 'message' => $error->getMessage(), 'trace' => $error->getTraceAsString(), 'context' => $this->getSecureContext() ]); // Generische Antwort für Client (keine Details) $publicMessage = match (true) { $error instanceof InvalidPasswordException => 'Authentication failed', $error instanceof TokenExpiredException => 'Token has expired', $error instanceof TokenInvalidException => 'Invalid token', $error instanceof CryptographicException => 'Security operation failed', default => 'Internal error occurred' }; return new ErrorResponse( message: $publicMessage, code: $this->getPublicErrorCode($error), timestamp: new DateTimeImmutable() ); } private function getSecureContext(): array { return [ 'request_id' => $this->generateRequestId(), 'user_agent_hash' => hash('sha256', $_SERVER['HTTP_USER_AGENT'] ?? ''), 'ip_hash' => hash('sha256', $_SERVER['REMOTE_ADDR'] ?? ''), 'timestamp' => time() ]; } private function generateRequestId(): string { return bin2hex(random_bytes(16)); } } ``` ## Monitoring und Alerting ### Security Monitoring ```php // ✅ Sicherheits-Monitoring für kryptographische Operationen final readonly class CryptographicSecurityMonitor { public function __construct( private MetricsCollector $metrics, private AlertManager $alerts, private SecurityEventLogger $securityLogger ) {} public function monitorOperation(string $operation, callable $callback): mixed { $startTime = microtime(true); $operationId = bin2hex(random_bytes(8)); try { $result = $callback(); // Erfolgreiche Operation protokollieren $duration = microtime(true) - $startTime; $this->metrics->increment("crypto.{$operation}.success"); $this->metrics->timing("crypto.{$operation}.duration", $duration); // Ungewöhnlich lange Operationen melden if ($duration > $this->getExpectedDuration($operation) * 2) { $this->alerts->sendAlert( level: 'warning', message: "Slow cryptographic operation: {$operation}", context: ['duration' => $duration, 'operation_id' => $operationId] ); } return $result; } catch (Throwable $e) { // Fehlgeschlagene Operation protokollieren $this->metrics->increment("crypto.{$operation}.failure"); $this->securityLogger->logCryptographicFailure($operation, $e, $operationId); // Bei kritischen Fehlern sofort alarmieren if ($this->isCriticalError($e)) { $this->alerts->sendAlert( level: 'critical', message: "Critical cryptographic failure: {$operation}", context: [ 'error' => $e->getMessage(), 'operation_id' => $operationId ] ); } throw $e; } } public function detectAnomalousPatterns(): void { // Erhöhte Fehlerrate erkennen $errorRate = $this->metrics->getRate('crypto.*.failure', '5m'); if ($errorRate > 0.1) { // >10% Fehlerrate $this->alerts->sendAlert( level: 'warning', message: 'High cryptographic error rate detected', context: ['error_rate' => $errorRate] ); } // Ungewöhnliche Aktivitätsmuster $operations = $this->metrics->getCount('crypto.*.success', '1h'); $baseline = $this->getHistoricalBaseline(); if ($operations > $baseline * 5) { $this->alerts->sendAlert( level: 'warning', message: 'Unusual spike in cryptographic operations', context: ['operations' => $operations, 'baseline' => $baseline] ); } } private function getExpectedDuration(string $operation): float { return match ($operation) { 'token_generation' => 0.001, // 1ms 'password_hash' => 0.5, // 500ms (Argon2ID) 'password_verify' => 0.5, // 500ms 'signature_create' => 0.01, // 10ms 'signature_verify' => 0.005, // 5ms default => 0.1 // 100ms }; } } ``` ## Compliance und Audit ### Compliance Framework ```php // ✅ Compliance-Unterstützung für Regulierungen final readonly class CryptographicComplianceValidator { private const COMPLIANCE_REQUIREMENTS = [ 'GDPR' => [ 'encryption_required' => true, 'key_length_min' => 256, 'algorithm_approved' => ['AES-256-GCM', 'ChaCha20-Poly1305'], 'key_rotation_days' => 365, 'audit_trail_required' => true ], 'PCI_DSS' => [ 'encryption_required' => true, 'key_length_min' => 256, 'algorithm_approved' => ['AES-256', 'RSA-2048'], 'key_rotation_days' => 365, 'secure_key_storage' => true ], 'FIPS_140_2' => [ 'approved_algorithms_only' => true, 'algorithm_approved' => ['AES', 'SHA-256', 'RSA', 'ECDSA'], 'random_number_generator' => 'FIPS_approved', 'key_length_min' => 256 ] ]; public function validateCompliance(string $standard): ComplianceReport { $requirements = self::COMPLIANCE_REQUIREMENTS[$standard] ?? throw new InvalidArgumentException("Unknown standard: {$standard}"); $violations = []; $report = new ComplianceReport($standard); // Algorithmus-Compliance prüfen if (isset($requirements['algorithm_approved'])) { $usedAlgorithms = $this->getUsedAlgorithms(); $approvedAlgorithms = $requirements['algorithm_approved']; foreach ($usedAlgorithms as $algorithm) { if (!in_array($algorithm, $approvedAlgorithms)) { $violations[] = "Non-approved algorithm in use: {$algorithm}"; } } } // Schlüssel-Längen prüfen if (isset($requirements['key_length_min'])) { $keyLengths = $this->getKeyLengths(); $minLength = $requirements['key_length_min']; foreach ($keyLengths as $context => $length) { if ($length < $minLength) { $violations[] = "Key length too short in {$context}: {$length} < {$minLength}"; } } } // Schlüssel-Rotation prüfen if (isset($requirements['key_rotation_days'])) { $rotationViolations = $this->checkKeyRotation($requirements['key_rotation_days']); $violations = array_merge($violations, $rotationViolations); } $report->setViolations($violations); $report->setCompliant(empty($violations)); return $report; } public function generateAuditReport(): AuditReport { return new AuditReport([ 'cryptographic_operations' => $this->getCryptoOperationStats(), 'key_management' => $this->getKeyManagementStats(), 'algorithm_usage' => $this->getAlgorithmUsageStats(), 'security_events' => $this->getSecurityEventSummary(), 'compliance_status' => $this->getComplianceStatus() ]); } } ``` Diese Sicherheitsrichtlinien stellen sicher, dass das Cryptography Module höchste Sicherheitsstandards erfüllt und gegen moderne Angriffsvektoren geschützt ist.