Files
Portfolio/blog-posts/68-iot-security.md
T
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

826 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```typescript
// 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
```typescript
// 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
```typescript
// 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
```typescript
// 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
```typescript
// 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
```typescript
// 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
- [IoT Device Security Best Practices 2026](https://www.jaycon.com/iot-device-security-best-practices/)
- [ConnectWise IoT Security Guide](https://www.connectwise.com/blog/how-to-secure-iot-devices)
- [Fortinet IoT Best Practices](https://www.fortinet.com/resources/cyberglossary/iot-best-practices)
- [Azure IoT Security](https://learn.microsoft.com/en-us/azure/iot/iot-overview-security)