Files
damjan_savicandClaude Opus 4.5 e1bbe5455d Initial commit: Portfolio Website
Vollständige Next.js 15 Portfolio-Website mit:
- Blog-System mit 100+ Artikeln
- Supabase-Integration
- Responsive Design mit Tailwind CSS
- TypeScript-Konfiguration
- Testing-Setup mit Vitest und Playwright

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:07:20 +01:00

21 KiB
Raw Permalink Blame History

IoT Security Best Practices

Meta-Description: IoT Security implementieren. Device Authentication, Verschlüsselung, Secure Boot und Firmware Updates für sichere IoT-Systeme.

Keywords: IoT Security, Device Authentication, TLS, Encryption, Secure Boot, Firmware Update, MQTT Security


Einführung

IoT-Sicherheit ist kritisch vernetzte Geräte sind potenzielle Angriffsziele. Device Authentication, Verschlüsselung, Secure Boot und sichere Firmware Updates sind Pflicht für jedes professionelle IoT-System.


IoT Security Layers

┌─────────────────────────────────────────────────────────────┐
│              IOT SECURITY ARCHITECTURE                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Layer 7 - Application Security:                            │
│  ├── Input Validation                                       │
│  ├── API Security (Rate Limiting, Auth)                    │
│  └── Secure Data Handling                                  │
│                                                             │
│  Layer 6 - Identity & Access:                               │
│  ├── Device Authentication (Certificates, Tokens)          │
│  ├── User Authentication (MFA, Passkeys)                   │
│  └── Role-Based Access Control (RBAC)                      │
│                                                             │
│  Layer 5 - Communication Security:                          │
│  ├── TLS 1.3 Encryption                                    │
│  ├── mTLS (Mutual TLS)                                     │
│  └── VPN / Private Networks                                │
│                                                             │
│  Layer 4 - Network Security:                                │
│  ├── Firewalls / Segmentation                              │
│  ├── Intrusion Detection (IDS)                             │
│  └── Traffic Monitoring                                    │
│                                                             │
│  Layer 3 - Device Security:                                 │
│  ├── Secure Boot                                           │
│  ├── Hardware Security Module (HSM)                        │
│  ├── Firmware Signing                                      │
│  └── Secure Storage (Encrypted)                            │
│                                                             │
│  Layer 2 - Physical Security:                               │
│  ├── Tamper Detection                                      │
│  ├── Secure Enclosure                                      │
│  └── Debug Port Disable                                    │
│                                                             │
│  Compliance: NIST, ISO 27001, IEC 62443, GDPR              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Device Authentication

// lib/device-auth.ts
import crypto from 'crypto';
import jwt from 'jsonwebtoken';

interface DeviceCredentials {
  deviceId: string;
  certificate: string;
  privateKey: string;
}

interface DeviceToken {
  deviceId: string;
  iat: number;
  exp: number;
  capabilities: string[];
}

class DeviceAuthenticator {
  private caCertificate: string;
  private jwtSecret: string;

  constructor(caCertPath: string, jwtSecret: string) {
    this.caCertificate = require('fs').readFileSync(caCertPath, 'utf8');
    this.jwtSecret = jwtSecret;
  }

  // X.509 Certificate-based Authentication
  verifyCertificate(clientCert: string): boolean {
    try {
      const cert = new crypto.X509Certificate(clientCert);
      const caCert = new crypto.X509Certificate(this.caCertificate);

      // Verify certificate chain
      if (!cert.verify(caCert.publicKey)) {
        return false;
      }

      // Check expiration
      const now = new Date();
      if (now < new Date(cert.validFrom) || now > new Date(cert.validTo)) {
        return false;
      }

      // Check revocation (in production: check CRL/OCSP)
      // ...

      return true;
    } catch (error) {
      console.error('Certificate verification failed:', error);
      return false;
    }
  }

  // Extract Device ID from Certificate
  extractDeviceId(clientCert: string): string | null {
    try {
      const cert = new crypto.X509Certificate(clientCert);
      // CN (Common Name) enthält Device ID
      const cnMatch = cert.subject.match(/CN=([^,]+)/);
      return cnMatch ? cnMatch[1] : null;
    } catch {
      return null;
    }
  }

  // JWT Token Generation für Devices
  generateDeviceToken(deviceId: string, capabilities: string[]): string {
    const payload: Omit<DeviceToken, 'iat' | 'exp'> = {
      deviceId,
      capabilities
    };

    return jwt.sign(payload, this.jwtSecret, {
      expiresIn: '24h',
      issuer: 'iot-platform',
      audience: 'iot-devices'
    });
  }

  // Token Verification
  verifyDeviceToken(token: string): DeviceToken | null {
    try {
      return jwt.verify(token, this.jwtSecret, {
        issuer: 'iot-platform',
        audience: 'iot-devices'
      }) as DeviceToken;
    } catch {
      return null;
    }
  }

  // Challenge-Response Authentication
  generateChallenge(): { challenge: string; expiresAt: Date } {
    const challenge = crypto.randomBytes(32).toString('hex');
    const expiresAt = new Date(Date.now() + 5 * 60 * 1000); // 5 Minuten

    return { challenge, expiresAt };
  }

  verifyChallenge(
    challenge: string,
    response: string,
    devicePublicKey: string
  ): boolean {
    try {
      const verify = crypto.createVerify('SHA256');
      verify.update(challenge);

      return verify.verify(devicePublicKey, response, 'base64');
    } catch {
      return false;
    }
  }
}

// API Key Authentication (für einfachere Devices)
interface APIKeyConfig {
  deviceId: string;
  apiKey: string;
  createdAt: Date;
  lastUsed?: Date;
  rateLimit: number;
}

class APIKeyAuthenticator {
  private keys: Map<string, APIKeyConfig> = new Map();

  generateKey(deviceId: string, rateLimit: number = 100): string {
    const apiKey = `iot_${crypto.randomBytes(24).toString('hex')}`;

    this.keys.set(apiKey, {
      deviceId,
      apiKey,
      createdAt: new Date(),
      rateLimit
    });

    return apiKey;
  }

  validateKey(apiKey: string): APIKeyConfig | null {
    const config = this.keys.get(apiKey);

    if (!config) {
      return null;
    }

    // Update last used
    config.lastUsed = new Date();

    return config;
  }

  revokeKey(apiKey: string): void {
    this.keys.delete(apiKey);
  }
}

TLS/mTLS Communication

// lib/secure-mqtt.ts
import mqtt from 'mqtt';
import fs from 'fs';
import tls from 'tls';

interface SecureMQTTConfig {
  brokerUrl: string;
  caCert: string;
  clientCert: string;
  clientKey: string;
  clientId: string;
}

function createSecureMQTTClient(config: SecureMQTTConfig): mqtt.MqttClient {
  return mqtt.connect(config.brokerUrl, {
    clientId: config.clientId,
    protocol: 'mqtts',
    protocolVersion: 5,  // MQTT 5.0

    // TLS Options
    ca: fs.readFileSync(config.caCert),
    cert: fs.readFileSync(config.clientCert),
    key: fs.readFileSync(config.clientKey),

    // Strict verification
    rejectUnauthorized: true,
    checkServerIdentity: (hostname, cert) => {
      // Custom hostname verification if needed
      return tls.checkServerIdentity(hostname, cert);
    },

    // Connection Options
    keepalive: 60,
    reconnectPeriod: 5000,
    connectTimeout: 30000,

    // Clean Session (MQTT 5.0)
    clean: true,
    properties: {
      sessionExpiryInterval: 0
    }
  });
}

// HTTPS Server mit mTLS
import https from 'https';
import express from 'express';

function createSecureServer(
  app: express.Application,
  caCert: string,
  serverCert: string,
  serverKey: string
) {
  return https.createServer({
    ca: fs.readFileSync(caCert),
    cert: fs.readFileSync(serverCert),
    key: fs.readFileSync(serverKey),

    // Require client certificates (mTLS)
    requestCert: true,
    rejectUnauthorized: true,

    // Minimum TLS version
    minVersion: 'TLSv1.3',

    // Cipher Suites (only strong ciphers)
    ciphers: [
      'TLS_AES_256_GCM_SHA384',
      'TLS_CHACHA20_POLY1305_SHA256',
      'TLS_AES_128_GCM_SHA256'
    ].join(':')
  }, app);
}

Secure Data Storage

// lib/secure-storage.ts
import crypto from 'crypto';
import { promisify } from 'util';

const scrypt = promisify(crypto.scrypt);

interface EncryptedData {
  iv: string;
  data: string;
  tag: string;
  salt: string;
}

class SecureStorage {
  private masterKey: Buffer | null = null;

  // Key Derivation von Password/PIN
  async deriveKey(password: string, salt: Buffer): Promise<Buffer> {
    return scrypt(password, salt, 32) as Promise<Buffer>;
  }

  // Initialize mit Master Key
  async initialize(masterPassword: string): Promise<void> {
    const salt = crypto.randomBytes(32);
    this.masterKey = await this.deriveKey(masterPassword, salt);
  }

  // AES-256-GCM Encryption
  encrypt(plaintext: string): EncryptedData {
    if (!this.masterKey) {
      throw new Error('Storage not initialized');
    }

    const iv = crypto.randomBytes(16);
    const salt = crypto.randomBytes(32);

    const cipher = crypto.createCipheriv('aes-256-gcm', this.masterKey, iv);

    let encrypted = cipher.update(plaintext, 'utf8', 'hex');
    encrypted += cipher.final('hex');

    const tag = cipher.getAuthTag();

    return {
      iv: iv.toString('hex'),
      data: encrypted,
      tag: tag.toString('hex'),
      salt: salt.toString('hex')
    };
  }

  // Decryption
  decrypt(encryptedData: EncryptedData): string {
    if (!this.masterKey) {
      throw new Error('Storage not initialized');
    }

    const iv = Buffer.from(encryptedData.iv, 'hex');
    const tag = Buffer.from(encryptedData.tag, 'hex');

    const decipher = crypto.createDecipheriv('aes-256-gcm', this.masterKey, iv);
    decipher.setAuthTag(tag);

    let decrypted = decipher.update(encryptedData.data, 'hex', 'utf8');
    decrypted += decipher.final('utf8');

    return decrypted;
  }

  // Secure Credential Storage
  async storeCredentials(
    deviceId: string,
    credentials: Record<string, string>
  ): Promise<EncryptedData> {
    const data = JSON.stringify({ deviceId, credentials, timestamp: Date.now() });
    return this.encrypt(data);
  }
}

// Hardware Security Module (HSM) Integration
interface HSMConfig {
  slotId: number;
  pin: string;
  modulePath: string;
}

class HSMIntegration {
  // Für echte HSM-Integration: PKCS#11 Library verwenden
  // z.B. graphene-pk11, pkcs11js

  async sign(data: Buffer, keyLabel: string): Promise<Buffer> {
    // HSM signing operation
    throw new Error('Implement with actual HSM library');
  }

  async verify(
    data: Buffer,
    signature: Buffer,
    keyLabel: string
  ): Promise<boolean> {
    // HSM verification
    throw new Error('Implement with actual HSM library');
  }

  async generateKeyPair(keyLabel: string): Promise<{ publicKey: string }> {
    // Generate key pair in HSM (private key never leaves HSM)
    throw new Error('Implement with actual HSM library');
  }
}

Secure Firmware Updates

// lib/firmware-update.ts
import crypto from 'crypto';
import fs from 'fs';
import { pipeline } from 'stream/promises';

interface FirmwareMetadata {
  version: string;
  releaseDate: string;
  sha256: string;
  signature: string;
  size: number;
  minVersion: string;
  deviceModels: string[];
}

class SecureFirmwareUpdater {
  private signingPublicKey: string;

  constructor(publicKeyPath: string) {
    this.signingPublicKey = fs.readFileSync(publicKeyPath, 'utf8');
  }

  // Firmware Signatur verifizieren
  verifySignature(firmwarePath: string, signature: string): boolean {
    const firmware = fs.readFileSync(firmwarePath);

    const verify = crypto.createVerify('SHA256');
    verify.update(firmware);

    return verify.verify(this.signingPublicKey, signature, 'base64');
  }

  // Firmware Hash verifizieren
  verifyHash(firmwarePath: string, expectedHash: string): boolean {
    const firmware = fs.readFileSync(firmwarePath);
    const hash = crypto.createHash('sha256').update(firmware).digest('hex');

    return hash === expectedHash;
  }

  // Firmware Download mit Verification
  async downloadFirmware(
    url: string,
    metadata: FirmwareMetadata,
    targetPath: string
  ): Promise<boolean> {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`Download failed: ${response.status}`);
    }

    // Streaming Download mit Hash-Berechnung
    const hash = crypto.createHash('sha256');
    const fileStream = fs.createWriteStream(targetPath);

    const reader = response.body?.getReader();
    if (!reader) throw new Error('No response body');

    let downloadedSize = 0;

    while (true) {
      const { done, value } = await reader.read();

      if (done) break;

      hash.update(value);
      fileStream.write(value);
      downloadedSize += value.length;
    }

    fileStream.end();

    // Size Check
    if (downloadedSize !== metadata.size) {
      fs.unlinkSync(targetPath);
      throw new Error('Size mismatch');
    }

    // Hash Check
    const actualHash = hash.digest('hex');
    if (actualHash !== metadata.sha256) {
      fs.unlinkSync(targetPath);
      throw new Error('Hash mismatch');
    }

    // Signature Check
    if (!this.verifySignature(targetPath, metadata.signature)) {
      fs.unlinkSync(targetPath);
      throw new Error('Signature verification failed');
    }

    return true;
  }

  // Version Check
  shouldUpdate(
    currentVersion: string,
    newVersion: string,
    minVersion: string
  ): boolean {
    const current = this.parseVersion(currentVersion);
    const target = this.parseVersion(newVersion);
    const min = this.parseVersion(minVersion);

    // Current version must be >= minVersion for update
    if (this.compareVersions(current, min) < 0) {
      return false;
    }

    // Only update if target is newer
    return this.compareVersions(target, current) > 0;
  }

  private parseVersion(version: string): number[] {
    return version.split('.').map(Number);
  }

  private compareVersions(a: number[], b: number[]): number {
    for (let i = 0; i < Math.max(a.length, b.length); i++) {
      const av = a[i] || 0;
      const bv = b[i] || 0;
      if (av > bv) return 1;
      if (av < bv) return -1;
    }
    return 0;
  }
}

// OTA Update API
import express from 'express';

const firmwareRouter = express.Router();

// GET /api/firmware/check?model=xxx&version=1.0.0
firmwareRouter.get('/check', async (req, res) => {
  const { model, version } = req.query;

  // Check for available updates
  const latestFirmware = await getLatestFirmware(model as string);

  if (!latestFirmware) {
    return res.json({ updateAvailable: false });
  }

  const updater = new SecureFirmwareUpdater('./keys/firmware-signing.pub');

  const shouldUpdate = updater.shouldUpdate(
    version as string,
    latestFirmware.version,
    latestFirmware.minVersion
  );

  res.json({
    updateAvailable: shouldUpdate,
    ...(shouldUpdate && { firmware: latestFirmware })
  });
});

Input Validation & Sanitization

// lib/input-validation.ts
import { z } from 'zod';

// Schema für Sensor-Daten
const SensorDataSchema = z.object({
  device_id: z.string()
    .min(1)
    .max(64)
    .regex(/^[a-zA-Z0-9_-]+$/),

  timestamp: z.string()
    .datetime()
    .refine(
      (ts) => new Date(ts) <= new Date(),
      'Timestamp cannot be in the future'
    ),

  temperature: z.number()
    .min(-50)
    .max(100)
    .optional(),

  humidity: z.number()
    .min(0)
    .max(100)
    .optional(),

  battery: z.number()
    .min(0)
    .max(100)
    .optional()
});

// Schema für Device Commands
const DeviceCommandSchema = z.object({
  action: z.enum(['restart', 'update', 'configure', 'reset']),
  target: z.string().min(1).max(64),
  payload: z.record(z.unknown()).optional()
}).refine(
  (data) => {
    // Dangerous actions require additional validation
    if (data.action === 'reset') {
      return data.payload?.confirm === true;
    }
    return true;
  },
  'Reset action requires confirmation'
);

// Middleware für Input Validation
import { Request, Response, NextFunction } from 'express';

function validateInput(schema: z.ZodType<any>) {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      req.body = schema.parse(req.body);
      next();
    } catch (error) {
      if (error instanceof z.ZodError) {
        return res.status(400).json({
          error: 'Validation failed',
          details: error.errors
        });
      }
      next(error);
    }
  };
}

// Rate Limiting
import rateLimit from 'express-rate-limit';

const deviceRateLimit = rateLimit({
  windowMs: 60 * 1000, // 1 Minute
  max: 60, // 60 Requests pro Minute
  keyGenerator: (req) => req.headers['x-device-id'] as string || req.ip,
  handler: (req, res) => {
    res.status(429).json({
      error: 'Rate limit exceeded',
      retryAfter: 60
    });
  }
});

Security Monitoring

// lib/security-monitoring.ts

interface SecurityEvent {
  timestamp: Date;
  eventType: string;
  severity: 'low' | 'medium' | 'high' | 'critical';
  deviceId?: string;
  sourceIp?: string;
  details: Record<string, any>;
}

class SecurityMonitor {
  private events: SecurityEvent[] = [];

  // Authentication Failure
  logAuthFailure(deviceId: string, reason: string, sourceIp: string): void {
    this.logEvent({
      eventType: 'auth_failure',
      severity: 'medium',
      deviceId,
      sourceIp,
      details: { reason }
    });

    // Check for brute force
    this.checkBruteForce(deviceId, sourceIp);
  }

  // Anomaly Detection
  logAnomaly(deviceId: string, anomalyType: string, value: any): void {
    this.logEvent({
      eventType: 'anomaly',
      severity: 'medium',
      deviceId,
      details: { anomalyType, value }
    });
  }

  // Firmware Tampering
  logTamperAttempt(deviceId: string, details: Record<string, any>): void {
    this.logEvent({
      eventType: 'tamper_attempt',
      severity: 'critical',
      deviceId,
      details
    });

    // Immediate alert
    this.sendAlert({
      type: 'tamper_attempt',
      deviceId,
      details
    });
  }

  private logEvent(event: Omit<SecurityEvent, 'timestamp'>): void {
    const fullEvent: SecurityEvent = {
      ...event,
      timestamp: new Date()
    };

    this.events.push(fullEvent);

    // In production: send to SIEM
    console.log('Security Event:', JSON.stringify(fullEvent));
  }

  private checkBruteForce(deviceId: string, sourceIp: string): void {
    const recentFailures = this.events.filter(e =>
      e.eventType === 'auth_failure' &&
      e.timestamp > new Date(Date.now() - 5 * 60 * 1000) &&
      (e.deviceId === deviceId || e.sourceIp === sourceIp)
    );

    if (recentFailures.length >= 5) {
      this.logEvent({
        eventType: 'brute_force_detected',
        severity: 'high',
        deviceId,
        sourceIp,
        details: { failureCount: recentFailures.length }
      });

      // Block IP/Device
      this.blockSource(sourceIp, deviceId);
    }
  }

  private blockSource(ip: string, deviceId: string): void {
    // Implement blocking logic
    console.log(`Blocking IP: ${ip}, Device: ${deviceId}`);
  }

  private sendAlert(alert: Record<string, any>): void {
    // Send to Slack, PagerDuty, etc.
    console.log('ALERT:', alert);
  }
}

Security Checklist

Category Requirement Priority
Authentication Certificate-based device auth High
Authentication No default credentials Critical
Encryption TLS 1.3 for all communications High
Encryption Data at rest encryption High
Firmware Signed firmware updates Critical
Firmware Secure boot chain High
Network Network segmentation Medium
Network Firewall rules High
Monitoring Security event logging High
Monitoring Anomaly detection Medium
Compliance Regular security audits High

Fazit

IoT Security erfordert:

  1. Defense in Depth: Mehrere Sicherheitsebenen
  2. Strong Authentication: Zertifikate statt Passwörter
  3. Encryption: TLS everywhere
  4. Secure Updates: Signierte Firmware

Sicherheit ist keine Option sie ist Pflicht.


Bildprompts

  1. "IoT security layers diagram, defense in depth concept"
  2. "Secure device authentication flow, certificate exchange"
  3. "Security monitoring dashboard with alerts and events"

Quellen