Verschluesselung ruhender Daten richtig einsetzen
Encryption at Rest schuetzt Daten auf gestohlenen Festplatten, in offenen Backups und in falsch konfigurierten Cloud-Storage-Buckets, aber sie ersetzt keine Anwendungssicherheit, denn eine laufende Applikation entschluesselt Daten fuer den Zugriff. Dieser Artikel zeigt, wie Datenbank-, Dateisystem- und Feld-Verschluesselung zusammenspielen und warum Key-Management dabei die eigentliche Herausforderung ist.
Inhaltsverzeichnis
- 1. Das Bedrohungsmodell: Was Encryption at Rest wirklich abdeckt
- 2. Was Encryption at Rest nicht schuetzt
- 3. Dateisystem- und Volume-Verschluesselung: LUKS, dm-crypt, Cloud-EBS
- 4. Datenbank-Verschluesselung: Transparent Data Encryption (TDE)
- 5. Feld-Level-Verschluesselung fuer PII-Spalten
- 6. Key-Management: der eigentliche Schwierigkeitsgrad
- 7. Magentos Crypt Key und EncryptorInterface
- 8. Suchbarkeit, Indizierung und Backup-Verschluesselung
- 9. Verschluesselungsebenen im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Das Bedrohungsmodell: Was Encryption at Rest wirklich abdeckt
Encryption at Rest schuetzt Daten, waehrend sie auf einem physischen oder virtuellen Speichermedium liegen und nicht aktiv von einer Anwendung verarbeitet werden. Das klassische Bedrohungsszenario ist der physische Diebstahl: eine gestohlene Festplatte aus einem Rechenzentrum, ein ausrangierter Server, der ohne sicheres Loeschen weiterverkauft wird, oder ein verlorenes Backup-Band. Ohne Verschluesselung liegen alle Daten im Klartext vor, sobald jemand physischen Zugriff auf das Speichermedium erhaelt, unabhaengig von jeder Anwendungslogik oder jedem Login-Formular.
Ein zweites, in der Cloud-Aera immer wichtigeres Szenario ist die Fehlkonfiguration von Storage: ein oeffentlich lesbarer S3-Bucket, ein falsch konfiguriertes Backup-Ziel oder ein Snapshot, der versehentlich mit einem anderen Kunden geteilt wird. Encryption at Rest verwandelt in diesen Faellen einen katastrophalen Datenabfluss in einen Vorfall mit deutlich geringerem Schaden, weil die Rohdaten ohne den passenden Schluessel wertlos bleiben. Genau deshalb verlangen PCI-DSS, DSGVO-Auslegungen und die meisten Auditstandards Verschluesselung fuer gespeicherte personenbezogene und zahlungsrelevante Daten, selbst wenn zusaetzliche Kontrollen wie Zugriffsmanagement bereits vorhanden sind.
2. Was Encryption at Rest nicht schuetzt
Der haeufigste Irrtum in Sicherheitsaudits ist die Annahme, verschluesselte Daten seien automatisch vor Anwendungsangriffen geschuetzt. Das stimmt nicht: Sobald eine Applikation laeuft, muss sie die Daten entschluesseln, um sie zu verarbeiten, und genau in diesem entschluesselten Zustand greifen SQL-Injection, kompromittierte Admin-Zugangsdaten oder eine ausgenutzte Remote-Code-Execution-Schwachstelle an. Ein Angreifer, der ueber eine SQL-Injection direkt Datenbankabfragen ausfuehrt, erhaelt die Ergebnisse genauso entschluesselt wie die Anwendung selbst, denn die Datenbank entschluesselt transparent fuer jeden authentifizierten Zugriff.
Auch ein kompromittierter Applikationsserver mit gueltiger Datenbankverbindung umgeht Encryption at Rest vollstaendig, weil die Verbindung selbst die Entschluesselung anstoesst. Das gilt ebenso fuer Insider-Bedrohungen mit legitimem Datenbankzugriff und fuer Backups, die im Rahmen eines regulaeren Restore-Vorgangs unverschluesselt in einer Test- oder Staging-Umgebung landen. Encryption at Rest ist damit eine Ergaenzung zu, nicht ein Ersatz fuer Eingabevalidierung, Least-Privilege-Zugriffskontrollen, Netzwerksegmentierung und die anderen OWASP-Kontrollen, die Angriffe auf laufende Systeme abwehren.
3. Dateisystem- und Volume-Verschluesselung: LUKS, dm-crypt, Cloud-EBS
Volume-Verschluesselung arbeitet unterhalb des Dateisystems und verschluesselt jeden Block, der auf die Platte geschrieben wird, vollstaendig transparent fuer Anwendungen und die Datenbank. Unter Linux ist LUKS mit dm-crypt der Standard: Nach dem Entsperren beim Boot verhaelt sich das Volume wie ein normales Blockgeraet, waehrend im ausgeschalteten Zustand oder bei einem gestohlenen Datentraeger alle Inhalte unlesbar bleiben. In der Cloud uebernehmen verwaltete Angebote wie AWS EBS-Verschluesselung, Azure Disk Encryption oder Google Persistent Disk Encryption dieselbe Funktion, meist per Checkbox aktivierbar und ohne messbaren Performance-Verlust bei modernen Prozessoren mit AES-NI.
Der grosse Vorteil von Volume-Verschluesselung ist die Einfachheit: Sie schuetzt alles auf dem Datentraeger gleichermassen, inklusive Konfigurationsdateien, Logs und temporaerer Dateien, ohne dass Anwendungscode angepasst werden muss. Der Nachteil ist ebenso grundlegend: Ein root-Zugriff auf das laufende, entsperrte System sieht alle Daten im Klartext, und ein Datenbankexport oder Backup, der das Volume verlaesst, ist nicht mehr durch diese Schicht geschuetzt. Volume-Verschluesselung ist damit die richtige Basisabsicherung gegen physischen Diebstahl, aber keine Loesung fuer selektiven Schutz einzelner sensibler Felder.
#!/usr/bin/env bash
# setup-luks-volume.sh - Create and mount a LUKS-encrypted data volume
set -euo pipefail
DEVICE="/dev/sdb1"
MAPPER_NAME="encrypted_data"
MOUNT_POINT="/var/lib/mysql-encrypted"
# Initialize LUKS2 header with AES-XTS and a strong key derivation function
cryptsetup luksFormat --type luks2 \
--cipher aes-xts-plain64 \
--key-size 512 \
--hash sha256 \
--pbkdf argon2id \
"$DEVICE"
# Open the encrypted volume, prompts for passphrase or reads from a keyfile
cryptsetup luksOpen "$DEVICE" "$MAPPER_NAME" --key-file /etc/luks/db.key
# Format and mount the now-unlocked block device like any other filesystem
mkfs.ext4 "/dev/mapper/${MAPPER_NAME}"
mkdir -p "$MOUNT_POINT"
mount "/dev/mapper/${MAPPER_NAME}" "$MOUNT_POINT"
# Register in /etc/crypttab for automatic unlock at boot via keyfile
echo "${MAPPER_NAME} UUID=$(blkid -s UUID -o value "$DEVICE") /etc/luks/db.key luks" >> /etc/crypttab
4. Datenbank-Verschluesselung: Transparent Data Encryption (TDE)
Transparent Data Encryption (TDE) verschluesselt Datendateien, Redo-Logs und Backups auf Ebene der Datenbank-Engine, ohne dass Anwendungscode oder SQL-Abfragen angepasst werden muessen. MySQL und MariaDB bieten dies ueber das InnoDB-Tablespace-Verschluesselungs-Plugin: Tabellenraeume werden mit einem Master-Key verschluesselt, der wiederum ueber ein Key-Management-Plugin, eine lokale Keyring-Datei oder einen externen KMS verwaltet wird. Der Vorteil gegenueber reiner Volume-Verschluesselung liegt in der granulareren Kontrolle: TDE laesst sich pro Tabellenraum aktivieren und schuetzt zusaetzlich Backups, die mit passenden Tools erstellt werden, waehrend ein rohes dd-Image des Datentraegers weiterhin unverschluesselt waere, wenn nur TDE ohne Volume-Verschluesselung aktiv ist.
TDE loest jedoch nicht das Problem eines authentifizierten Datenbankzugriffs: Jede Query, die die Datenbank normal beantwortet, liefert entschluesselte Werte zurueck, weil die Engine transparent fuer den Anwendungsprozess entschluesselt. Wer also gezielten Schutz fuer einzelne hochsensible Spalten wie Sozialversicherungsnummern oder Zahlungsdaten braucht, kombiniert TDE typischerweise mit Feld-Level-Verschluesselung fuer genau diese Spalten. In der Praxis ist TDE der richtige Standardschutz fuer die gesamte Datenbank gegen Backup-Diebstahl und physischen Zugriff, waehrend Feld-Verschluesselung zusaetzliche Kontrolle fuer die kritischsten Datenpunkte liefert.
5. Feld-Level-Verschluesselung fuer PII-Spalten
Bei Feld-Level-Verschluesselung verschluesselt die Anwendung selektiv einzelne Spalten, bevor sie in die Datenbank geschrieben werden, und entschluesselt sie erst beim tatsaechlichen Lesevorgang im Anwendungscode. Damit bleiben diese Werte selbst fuer einen Datenbankadministrator mit vollem SQL-Zugriff unlesbar, solange dieser nicht auch den Anwendungsschluessel besitzt, ein deutlich staerkeres Schutzniveau als TDE fuer die betroffenen Spalten. Typische Kandidaten sind Sozialversicherungsnummern, Bankverbindungen, Gesundheitsdaten oder andere Felder mit besonders hoher Sensitivitaet, waehrend weniger kritische Spalten wie Produktnamen oder Bestellstatus unverschluesselt bleiben koennen.
Fuer die Implementierung in PHP ist AES-256-GCM mit authentifizierter Verschluesselung der aktuelle Standard, verfuegbar sowohl ueber OpenSSL als auch ueber libsodium. Entscheidend ist eine fuer jede Verschluesselungsoperation neu generierte Nonce, niemals eine wiederverwendete oder vorhersagbare, da eine Nonce-Wiederverwendung bei GCM den gesamten Authentizitaetsschutz aushebeln kann. Das Authentication-Tag von GCM erkennt zusaetzlich jede nachtraegliche Manipulation der verschluesselten Daten und macht die Verschluesselung damit robuster als reine Confidentiality-Modi wie CBC ohne separate HMAC-Absicherung.
<?php
declare(strict_types=1);
namespace Mironsoft\PiiEncryption\Model;
/**
* Field-level encryption for highly sensitive PII columns using AES-256-GCM.
* Uses a fresh random nonce per operation and an authentication tag to detect tampering.
*/
final class FieldEncryptor
{
private const CIPHER = 'aes-256-gcm';
private const NONCE_LENGTH = 12; // 96-bit nonce recommended for GCM
public function __construct(
private readonly string $keyBinary // 32-byte key, loaded from a KMS or secrets manager
) {
}
/**
* Encrypts a plaintext PII value and returns nonce, tag and ciphertext packed together.
*
* @param string $plaintext Sensitive value to encrypt, e.g. a national ID number
* @return string Base64-encoded payload: nonce || tag || ciphertext
*/
public function encrypt(string $plaintext): string
{
$nonce = random_bytes(self::NONCE_LENGTH); // never reuse a nonce with the same key
$tag = '';
$ciphertext = openssl_encrypt(
$plaintext,
self::CIPHER,
$this->keyBinary,
OPENSSL_RAW_DATA,
$nonce,
$tag
);
if ($ciphertext === false) {
throw new \RuntimeException('Field encryption failed.');
}
return base64_encode($nonce . $tag . $ciphertext);
}
/**
* Decrypts a previously encrypted field value and verifies the authentication tag.
*
* @param string $payload Base64-encoded nonce || tag || ciphertext
* @return string The original plaintext value
*/
public function decrypt(string $payload): string
{
$raw = base64_decode($payload, true);
$nonce = substr($raw, 0, self::NONCE_LENGTH);
$tag = substr($raw, self::NONCE_LENGTH, 16); // GCM tag is 16 bytes
$ciphertext = substr($raw, self::NONCE_LENGTH + 16);
$plaintext = openssl_decrypt(
$ciphertext,
self::CIPHER,
$this->keyBinary,
OPENSSL_RAW_DATA,
$nonce,
$tag
);
if ($plaintext === false) {
// Tag mismatch means the ciphertext was tampered with or the key is wrong
throw new \RuntimeException('Field decryption failed: authentication tag mismatch.');
}
return $plaintext;
}
}
6. Key-Management: der eigentliche Schwierigkeitsgrad
Verschluesselungsalgorithmen selbst sind seit Jahren geloest, das eigentlich schwierige Problem ist Key-Management: wo Schluessel gespeichert werden, wer darauf zugreifen darf, wie sie rotiert werden und was bei einem kompromittierten Schluessel passiert. Ein Schluessel, der neben den verschluesselten Daten in derselben Datenbank oder im selben Anwendungscode liegt, bietet keinen echten Schutz, weil ein Angreifer mit Datenbankzugriff beides gleichzeitig erhaelt. Die grundlegende Regel lautet deshalb: Schluessel und verschluesselte Daten muessen in getrennten Vertrauenszonen liegen, idealerweise mit unterschiedlichen Zugriffspfaden und unterschiedlicher Protokollierung.
Fuer produktive Systeme sind dedizierte Key-Management-Systeme wie AWS KMS, HashiCorp Vault oder ein Hardware Security Module (HSM) der richtige Ansatz. Sie uebernehmen Schluesselerzeugung, automatische Rotation nach einem definierten Zeitplan, Zugriffsprotokollierung und die Moeglichkeit, einen Schluessel sofort zu widerrufen, ohne den physischen Schluesselwert jemals aus dem sicheren Speicher zu exportieren. Envelope Encryption ist dabei das dominante Muster: Ein Data Encryption Key verschluesselt die eigentlichen Daten, waehrend ein uebergeordneter Key Encryption Key im KMS diesen Data Encryption Key schuetzt. Rotation des Key Encryption Key erfordert dann keine Neuverschluesselung aller Daten, sondern nur eine Neuverschluesselung der deutlich kleineren Data Encryption Keys.
{
"keyRotationPolicy": {
"keyId": "arn:aws:kms:eu-central-1:123456789012:key/pii-field-encryption",
"rotationEnabled": true,
"rotationIntervalDays": 90,
"envelopeEncryption": {
"keyEncryptionKey": "kms-managed",
"dataEncryptionKeyAlgorithm": "AES-256-GCM",
"dataEncryptionKeyCacheTtlSeconds": 300
},
"accessPolicy": {
"allowedPrincipals": [
"role/magento-app-encrypt-service"
],
"requireMfaForDecrypt": false,
"requireMfaForKeyDeletion": true,
"auditLogging": "cloudtrail-enabled"
},
"keyDeletionWindowDays": 30
}
}
7. Magentos Crypt Key und EncryptorInterface
Magento bringt ein eigenes Verschluesselungsmodell mit, das auf einem in app/etc/env.php gespeicherten Crypt Key basiert. Dieser Schluessel wird bei der Installation generiert und von Magento\Framework\Encryption\EncryptorInterface fuer alle sensiblen Konfigurationswerte verwendet, etwa API-Zugangsdaten in core_config_data, Zahlungsgateway-Credentials und bestimmte Kundenwerte. Intern nutzt der Encryptor je nach Magento-Version AES-256-GCM oder aeltere Modi mit HMAC-Absicherung, wobei alle produktiven Magento-2.4.x-Installationen standardmaessig authentifizierte Verschluesselung verwenden. Wichtig fuer den Betrieb: Geht der Crypt Key verloren oder wird er ohne vorherige Neuverschluesselung ausgetauscht, werden alle damit verschluesselten Konfigurationswerte unlesbar, weshalb er zwingend Teil jeder Backup-Strategie sein muss, getrennt von der eigentlichen Datenbank gesichert.
Fuer eigene Module ist der Encryptor die richtige Anlaufstelle, um zusaetzliche sensible Felder zu schuetzen, statt eine eigene Kryptografie-Implementierung zu bauen. Die Klasse kapselt Nonce-Erzeugung, Padding und Schluesselversionierung korrekt und unterstuetzt Encryptor::decrypt() auch fuer aeltere Verschluesselungsversionen nach einem Crypt-Key-Rotation-Vorgang. Wer stattdessen mit rohem openssl_encrypt() ohne Versionsverwaltung arbeitet, riskiert nach einer Schluesselrotation unentschluesselbare Altdaten, weil keine Zuordnung mehr existiert, mit welchem Schluessel welcher Wert urspruenglich verschluesselt wurde.
<?php
declare(strict_types=1);
namespace Mironsoft\CustomerVault\Model;
use Magento\Framework\Encryption\EncryptorInterface;
/**
* Encrypts and decrypts a sensitive customer attribute using Magento's own
* crypt key infrastructure instead of a custom implementation.
*/
final class SensitiveAttributeHandler
{
public function __construct(
private readonly EncryptorInterface $encryptor
) {
}
/**
* Encrypts a sensitive value before persisting it, e.g. a national tax ID.
*
* @param string $rawValue Plaintext value entered by the customer
* @return string Encrypted value ready for storage in a custom attribute
*/
public function encryptForStorage(string $rawValue): string
{
// Uses the crypt key from app/etc/env.php with versioned, authenticated encryption
return $this->encryptor->encrypt($rawValue);
}
/**
* Decrypts a stored value for display, honoring old key versions after rotation.
*
* @param string $storedValue Encrypted value as read from the database
* @return string Decrypted plaintext value
*/
public function decryptForDisplay(string $storedValue): string
{
// decrypt() transparently handles values encrypted with a prior key version
return $this->encryptor->decrypt($storedValue);
}
}
8. Suchbarkeit, Indizierung und Backup-Verschluesselung
Feld-Level-Verschluesselung hat einen erheblichen praktischen Nachteil: Verschluesselte Spalten sind mit Standard-SQL nicht mehr durchsuchbar oder sortierbar, weil derselbe Klartext bei korrekter Nonce-Verwendung jedes Mal einen anderen Chiffretext ergibt. WHERE email = 'x@y.de' funktioniert gegen eine verschluesselte E-Mail-Spalte nicht mehr. Die gaengigen Loesungsansaetze sind ein zusaetzlicher deterministischer HMAC-Index fuer exakte Gleichheitssuchen, ein separater Suchindex ausserhalb der Datenbank oder der bewusste Verzicht auf Verschluesselung fuer Felder, die zwingend durchsuchbar bleiben muessen, kombiniert mit staerkeren Zugriffskontrollen als Ausgleich. Diese Abwaegung sollte projektspezifisch und dokumentiert getroffen werden, nicht implizit durch die erstbeste Implementierung.
Backups verdienen dieselbe Sorgfalt wie die Live-Datenbank, werden in der Praxis aber haeufig vernachlaessigt. Ein mysqldump, der unverschluesselt auf einem Netzlaufwerk oder in einem falsch konfigurierten Cloud-Bucket landet, hebelt jede Datenbankverschluesselung vollstaendig aus. Die korrekte Pipeline verschluesselt den Dump direkt beim Erstellen, bevor er das Quellsystem verlaesst, und verwendet dafuer einen eigenen, vom Datenbankschluessel getrennten Backup-Schluessel, damit ein kompromittierter Anwendungsschluessel nicht automatisch auch alle historischen Backups offenlegt.
#!/usr/bin/env bash
# encrypted-backup.sh - Dump the Magento database and encrypt it before it leaves the host
set -euo pipefail
DB_NAME="magento"
BACKUP_DIR="/var/backups/magento"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
GPG_RECIPIENT="backups@mironsoft.de"
mkdir -p "$BACKUP_DIR"
# Stream the dump directly into gpg, plaintext data never touches disk unencrypted
mysqldump --single-transaction --quick --routines "$DB_NAME" \
| gzip -9 \
| gpg --encrypt --recipient "$GPG_RECIPIENT" --trust-model always \
> "${BACKUP_DIR}/${DB_NAME}-${TIMESTAMP}.sql.gz.gpg"
# Verify the encrypted archive is well-formed before considering the backup successful
gpg --list-packets "${BACKUP_DIR}/${DB_NAME}-${TIMESTAMP}.sql.gz.gpg" > /dev/null
echo "[OK] Encrypted backup written: ${DB_NAME}-${TIMESTAMP}.sql.gz.gpg"
9. Verschluesselungsebenen im direkten Vergleich
Die drei Verschluesselungsebenen schuetzen unterschiedliche Angriffsszenarien und lassen sich sinnvoll kombinieren statt gegeneinander auszuspielen. Die folgende Uebersicht zeigt, was jede Ebene abdeckt und wo sie an ihre Grenzen stoesst.
| Ebene | Schuetzt vor | Schuetzt nicht vor | Einsatzempfehlung |
|---|---|---|---|
| Volume/LUKS | Physischer Diebstahl der Platte | Zugriff auf laufendes, entsperrtes System | Basisschutz fuer jeden Server, ohne Ausnahme |
| DB-Level TDE | Gestohlene Backups, Tablespace-Dateien | Authentifizierte SQL-Abfragen, SQL-Injection | Standardschutz fuer die gesamte Datenbank |
| Feld-Level | DBA-Zugriff, kompromittierte DB-Credentials | Kompromittierten App-Server mit Entschluesselungsrecht | Nur fuer hochsensible PII-Spalten gezielt einsetzen |
| Magento Crypt Key | Konfigurationswerte, API-Credentials | Anwendungsschwachstellen wie XSS oder RCE | Immer ueber EncryptorInterface, nie eigene Krypto |
| Unverschluesseltes Backup | Nichts | Hebelt alle anderen Ebenen bei Backup-Diebstahl aus | Niemals ohne separate Backup-Verschluesselung |
Mironsoft
Datensicherheit, Key-Management und Verschluesselungskonzepte fuer Magento-Shops
Ruhende Daten wirklich absichern?
Wir pruefen euer Verschluesselungskonzept fuer Datenbank, Backups und PII-Felder, richten Key-Management sauber ein und implementieren Feld-Level-Verschluesselung dort, wo sie tatsaechlich einen Unterschied macht.
Verschluesselungs-Audit
Analyse von Volume-, DB- und Feld-Verschluesselung im Bestand
Key-Management-Setup
KMS/Vault-Integration, Rotation und Envelope Encryption aufbauen
PII-Feldverschluesselung
AES-256-GCM-Implementierung fuer sensible Kundenattribute
10. Zusammenfassung
Data Encryption at Rest loest ein klar umrissenes Problem: Schutz vor physischem Diebstahl, verlorenen oder gestohlenen Backups und falsch konfigurierten Storage-Umgebungen. Volume-Verschluesselung mit LUKS oder Cloud-EBS-Verschluesselung ist der richtige Basisschutz fuer jeden Server, TDE auf Datenbankebene ergaenzt das um granularen Schutz fuer Tablespaces und Backups, und Feld-Level-Verschluesselung mit AES-256-GCM schuetzt gezielt die kritischsten PII-Spalten selbst vor Datenbankadministratoren. Keine dieser Ebenen ersetzt Anwendungssicherheit, denn eine laufende Applikation entschluesselt Daten zwangslaeufig fuer die Verarbeitung.
Der eigentliche Schwierigkeitsgrad liegt nicht in der Kryptografie selbst, sondern im Key-Management: getrennte Vertrauenszonen fuer Schluessel und Daten, automatische Rotation, Envelope Encryption und eine dedizierte Loesung wie AWS KMS oder HashiCorp Vault statt selbstgebauter Schluesselverwaltung. Magento-Betreiber sollten den Crypt Key aus app/etc/env.php konsequent als kritisches Secret behandeln, EncryptorInterface fuer eigene sensible Felder nutzen und Backups grundsaetzlich verschluesselt erstellen, bevor sie das Quellsystem verlassen.
Data Encryption at Rest - Das Wichtigste auf einen Blick
Bedrohungsmodell
Schuetzt vor physischem Diebstahl und Backup-Exposure, nicht vor SQL-Injection oder kompromittierten App-Zugangsdaten.
Drei Ebenen kombinieren
LUKS/Cloud-Volume-Verschluesselung als Basis, TDE fuer die Datenbank, Feld-Level-Verschluesselung fuer hochsensible PII-Spalten.
Key-Management ist der Kern
Getrennte Vertrauenszonen, Rotation und Envelope Encryption ueber KMS/Vault statt selbstgebauter Schluesselverwaltung.
Magento Crypt Key
EncryptorInterface nutzen statt eigener Kryptografie, Crypt Key aus app/etc/env.php als kritisches Secret behandeln.