Verschlüsselung unter Debian 13 und CachyOS: LUKS, Dateien, Archive
„Verschlüsselung“ ist kein Schalter, sondern eine Frage der Ebene: Transport (TLS, SSH), Datenträger (LUKS), einzelne Dateien und Ordner (gocryptfs, rclone crypt) und Archive und Backups (7z, age, GPG, restic). Dieser Artikel sortiert die vier Ebenen für Debian 13 und CachyOS – mit echten Ausgaben: einem LUKS2-Header, gemessenem Krypto-Durchsatz (AES-XTS 15,7 GB/s gegen Serpent 0,9 GB/s), der Argon2id-Kostenrechnung und dem SSH-Schlüsselformat, das niemand je zu Gesicht bekommt. Dazu die Dinge, die in Anleitungen fehlen: Header-Backup, PBKDF umstellen (sonst kein GRUB), TPM2 ohne Passphrase und nachträgliches Verschlüsseln im laufenden Betrieb.
Vier Ebenen, vier Werkzeuge
Die häufigste Enttäuschung beim Thema Verschlüsselung entsteht durch die falsche Ebene: Ein verschlüsseltes Backup-Archiv schützt nicht den laufenden Server, ein LUKS-Container schützt keine E-Mail auf dem Weg, und eine TLS-Verbindung schützt keine Festplatte, die verkauft wird.
| Ebene | Was geschützt wird | Werkzeuge | Schlüssel liegt … |
|---|---|---|---|
| Transport | Die Leitung, nicht die Enden | TLS, SSH, WireGuard | Im Zertifikat/auf dem Endpunkt – der Server sieht alles im Klartext |
| Datenträger | Alles auf dem Blockgerät, inklusive Metadaten der Dateien | LUKS2 (cryptsetup), VeraCrypt | Im LUKS-Header, geschützt durch Passphrase/Keyfile/TPM |
| Dateien und Ordner | Einzelne Verzeichnisse, auch in der Cloud | gocryptfs, rclone crypt, fscrypt | In einer Datei in deinem Besitz – der Server sieht nur Chiffrat |
| Archive und Backups | Daten, die das System verlassen (USB, Cloud, Remotes) | 7z, age, GPG, restic, borg | Passphrase oder Schlüsseldatei – nicht im gleichen Ordner |
Und genauso wichtig: Was Verschlüsselung nicht leistet.
| Erwartung | Realität |
|---|---|
| „Verschlüsselt heißt unauffindbar“ | Auf einem LUKS-Gerät sieht man von außen Zufallsdaten, aber Existenz und Größe sind sichtbar |
| „Ein Backup passiert automatisch entschlüsselt“ | Backup-Ziele sind meist unverschlüsselt – Verschlüsselung macht man in der Software, nicht am Ziel |
| „Das laufende System ist geschützt“ | Ist das System entsperrt, liegen die Daten im Klartext und im RAM; ein Angreifer mit root liest mit |
| „Passphrase vergessen ist nicht schlimm“ | Der Schlüssel ist die Passphrase: ohne sie bleiben die Daten für immer verborgen |
| „Metadaten sind sowieso weg“ | Auf einem Datenträger ja, im Dateibetrieb nicht – Dateinamen und Größen sind nur mit Container-/Verzeichnisverschlüsselung geschützt |
Was Verschlüsselung wirklich kostet
Bevor man über Verfahren diskutiert, hilft eine Messung auf der eigenen Maschine.
cryptsetup bringt dazu einen Benchmark mit, der die CPU-Leistung der Kernel-Krypto-Schnittstelle
misst – ohne einen Datenträger zu berühren. Auf dem Testsystem (Ryzen 9 9950X3D, cryptsetup
2.8.7 mit KERNEL_CAPI-Unterstützung) ergibt das:
cryptsetup benchmark
PBKDF2-sha1 6061132 Iterationen pro Sekunde für 256-Bit-Schlüssel
PBKDF2-sha256 9664294 Iterationen pro Sekunde für 256-Bit-Schlüssel
PBKDF2-sha512 4619277 Iterationen pro Sekunde für 256-Bit-Schlüssel
argon2i 19 Iterationen, 1048576 Speicher, 4 parallele Threads (Zieldauer 2000 ms)
argon2id 19 Iterationen, 1048576 Speicher, 4 parallele Threads (Zieldauer 2000 ms)
# Algorithmus | Schlüssel | Verschlüsselung | Entschlüsselung
aes-cbc 128b 1783,0 MiB/s 9195,2 MiB/s
serpent-cbc 128b 189,0 MiB/s 1124,7 MiB/s
twofish-cbc 128b 382,5 MiB/s 926,6 MiB/s
aes-cbc 256b 1333,3 MiB/s 7211,9 MiB/s
aes-xts 256b 15764,0 MiB/s 15822,7 MiB/s
serpent-xts 256b 900,6 MiB/s 1022,6 MiB/s
twofish-xts 256b 848,6 MiB/s 872,6 MiB/s
aes-xts 512b 14192,7 MiB/s 14242,0 MiB/s
Drei Zahlen daraus sind die ganze Diskussion:
| Wert | Bedeutung | Konsequenz |
|---|---|---|
aes-xts 256b: 15,7 GB/s | Der Durchsatz der Festplattenverschlüsselung auf dieser CPU | Deutlich mehr als jede NVMe liefert (Größenordnung 3–14 GB/s) – Verschlüsselung ist hier kein Flaschenhals |
serpent-xts: 0,9 GB/s | Ohne Hardwarebeschleunigung (kein VAES/AES-NI für Serpent) | Genau deshalb ist AES-XTS der Standard: nicht wegen Sicherheit, sondern wegen Speed |
argon2id: 1 GiB, 19 Iterationen | Kosten einer einzigen Passphrase-Prüfung (Zieldauer 2 s) | Das ist der Grund für die Gedenksekunde beim Entsperren – und der Schutz gegen Wörterbuchangriffe |
Warum AES so schnell ist, verrät der Kernel direkt – hier die tatsächlich benutzte Implementierung:
grep -A8 -m1 'name : xts(aes)' /proc/crypto
name : xts(aes)
driver : xts-aes-vaes-avx512
module : aesni_intel
priority : 800
selftest : passed
type : skcipher
vaes-avx512 heißt: Der Prozessor rechnet AES in Vektorregistern, mehrere Blöcke parallel.
Auf älteren CPUs steht dort xts-aes-aesni oder – ohne AES-NI – eine Softwarevariante mit einem
Bruchteil des Durchsatzes. Für Transportverschlüsselung (TLS, VPN) sind die Zahlen ähnlich eindeutig:
openssl speed -seconds 1 -evp aes-256-gcm # Auszug (1000 Byte/s)
AES-256-GCM 196873.39k … 20114489.34k 23134406.59k
16 B → 0,2 GB/s | 16 KB → 23,1 GB/s
openssl speed -seconds 1 -evp chacha20-poly1305
ChaCha20-Poly1305 374769.05k … 6563414.02k
16 B → 0,37 GB/s | 16 KB → 6,6 GB/s
openssl speed -seconds 1 ed25519
sign verify sign/s verify/s
EdDSA (Ed25519) 0.0000s 0.0001s 61909.1 18056.0
LUKS2: Datenträger verschlüsseln
Der Einstieg passiert bei der Installation: Debian 13 bietet im Installer „verschlüsseltes LVM“ (LUKS2 seit Debian 12 als Standard), CachyOS bietet im Calamares-Installer die Option „Verschlüsselt“ mit LUKS2. Wer beides nicht angeklickt hat, kann später nachrüsten (siehe Nachträglich verschlüsseln).
Für eigene Datenträger genügen drei Befehle. Wichtig ist --type luks2 (Argon2id statt
PBKDF2+Anti-Forensik-Stripes) und eine Passphrase, die nicht im Verlauf landet:
# Debian 13
sudo apt install cryptsetup cryptsetup-initramfs
# CachyOS / Arch
sudo pacman -S cryptsetup
# Datenträger verschlüsseln (VORSICHT: löscht alles auf /dev/sdX)
sudo cryptsetup luksFormat --type luks2 /dev/sdX1
# Öffnen (verlangt die Passphrase) und Dateisystem anlegen
sudo cryptsetup open /dev/sdX1 daten
sudo mkfs.ext4 /dev/mapper/daten
sudo mount /dev/mapper/daten /mnt/daten
Was LUKS2 dabei anlegt, zeigt der Header – hier eine echte Ausgabe eines Testcontainers (Header auf einer Datei erzeugt, ohne root):
cryptsetup luksDump t.img
LUKS header information
Version: 2
Epoch: 3
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 29e4b34e-2fe4-4370-aaf0-24924ab494d5
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 4096 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 19
Memory: 1048576
Threads: 4
Salt: 62 b1 c3 f0 e2 75 b9 1d …
AF stripes: 4000
AF hash: sha256
| Feld | Bedeutung | Warum es dich interessiert |
|---|---|---|
Metadata area: 16384 | Binäre Metadaten (JSON im gleichen Bereich) | Teil des Headers, den du sichern musst |
Keyslots area: 16744448 | Platz für alle Keyslots | Erklärt, warum eine Header-Sicherung groß ist (unten: 16 MiB) |
offset: 16777216 | Daten beginnen erst nach 16 MiB | Deshalb ist die Header-Sicherung 16 MiB groß – und deshalb „verschwendet“ LUKS2 etwas Platz |
sector: 4096 | Verschlüsselung in 4-KiB-Sektoren | Passt zu modernen NVMe/Datenträgern; 512-Byte-Sektoren sind für alte Hardware/GRUB nötig |
cipher: aes-xts-plain64 | Das Standardverfahren | XTS deckt Muster ab, die ECB/CBC auf Platten erzeugen würden |
PBKDF: argon2id, Memory: 1048576 | 1 GiB Speicher pro Prüfversuch, ~19 Runden | Macht Wörterbuchangriffe teuer – und das Entsperren langsam (rund 2 s) |
/boot-Partition ist das kein Thema.
LUKS im Betrieb: Keyslots, crypttab, Keyfiles
Jeder „Schlüssel“ steckt in einem eigenen Keyslot. Das ist der Mechanismus, mit dem man eine Passphrase ändert oder zusätzlich ein Keyfile (z. B. für das NAS) hinterlegt, ohne alles neu zu verschlüsseln. Die folgende Ausgabe stammt aus dem Testcontainer: erst ein Keyfile, dann ein zweiter Keyslot, dann die Umstellung von Slot 0 auf PBKDF2 für GRUB-Kompatibilität:
# zweiten Keyslot anlegen (Keyfile statt Passphrase)
cryptsetup luksAddKey --key-file key1 t.img key2
cryptsetup luksDump t.img | grep -E '^ [0-9]+: luks2|PBKDF|Memory'
0: luks2
PBKDF: argon2id
Memory: 1048576
1: luks2
PBKDF: argon2id
Memory: 1048576
# Keyslot 0 auf PBKDF2 umstellen (nötig, wenn GRUB die Passphrase abfragen soll)
cryptsetup luksConvertKey --key-file key1 --pbkdf pbkdf2 --pbkdf-force-iterations 1000000 t.img
cryptsetup luksDump t.img | grep -A6 '^ 0: luks2'
0: luks2
Key: 512 bits
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: pbkdf2
Hash: sha256
| Aufgabe | Befehl | Hinweis |
|---|---|---|
| Passphrase ändern | sudo cryptsetup luksChangeKey /dev/sdX | Ändert nur den Keyslot – die Daten bleiben, wo sie sind |
| Zusätzlichen Schlüssel hinterlegen | sudo cryptsetup luksAddKey --key-file alt /dev/sdX neu.key | Ideal für automatisches Öffnen ohne Passphrase-Eingabe |
| Keyslot löschen | sudo cryptsetup luksKillSlot /dev/sdX 1 | Nach dem Ausscheiden von Personen/Systemen zwingend |
| Header und Keyslots ansehen | sudo cryptsetup luksDump /dev/sdX | Mit --dump-json-metadata maschinenlesbar (LUKS2) |
| PBKDF umstellen (GRUB) | sudo cryptsetup luksConvertKey --pbkdf pbkdf2 --pbkdf-force-iterations 1000000 /dev/sdX | Argon2id bleibt sonst unlesbar für GRUB |
| Datenträger prüfen | cryptsetup isLuks /dev/sdX && echo ok | Schneller Test, ob es ein LUKS-Container ist (funktioniert auch als normaler Nutzer) |
| Beim Start automatisch öffnen | /etc/crypttab + /etc/fstab | Auf beiden Distributionen identisch, weil beide systemd nutzen |
# /etc/crypttab – Feld 2 ist die Keyfile mit den Rechten 0400, root:root
# <Name> <Gerät> <Keyfile> <Optionen>
daten UUID=… /etc/luks/daten.key luks,discard,nofail
# Passphrase zusätzlich verlangen (statt nur Keyfile): Schlüsselwort "none" im Keyfile-Feld
systemd-cryptsetup-generator --help # erzeugt die Units automatisch aus crypttab
systemctl status systemd-cryptsetup@daten.service
discard ist eine Abwägung, keine Kleinigkeit. TRIM durch den verschlüsselten
Layer macht SSDs schneller und langlebiger, verrät aber, welche Blöcke belegt sind. Wer „keine Rückschlüsse
auf Datenmuster“ braucht, lässt TRIM weg und nimmt den Performanceverlust in Kauf – oder verlässt sich auf
die SSD-eigene Verschlüsselung zusätzlich zum LUKS-Container.
Der LUKS-Header: dein wertvollstes Datum
Der LUKS-Header enthält alles, was zum Öffnen nötig ist: die Keyslots, die mit deiner Passphrase geschützten Hauptschlüssel und die Metadaten. Ist der Header weg, sind die Daten weg – auch mit korrekter Passphrase. Deshalb gehört er in jedes Backup:
# Header sichern (Datei wie ein Passwort behandeln!)
sudo cryptsetup luksHeaderBackup /dev/sdX --header-backup-file /root/luks-header-sdX.img
ls -la /root/luks-header-sdX.img
-r-------- 1 root root 16777216 … luks-header-sdX.img # 16 MiB bei LUKS2
# Wiederherstellen (z. B. nach versehentlichem luksFormat)
sudo cryptsetup luksHeaderRestore /dev/sdX --header-backup-file /root/luks-header-sdX.img
| Fall | Ohne Header-Backup | Mit Header-Backup |
|---|---|---|
| Partitionstabelle/Anfang überschrieben | Daten verloren, auch mit Passphrase | Header zurückspielen, Daten wieder da |
Falsche Passphrase zu oft eingegeben (Debian: cryptsetup-nuke-password) | Keyslots gelöscht → unwiederbringlich | Header mit gültigen Keyslots zurückspielen |
| SSD defekt, aber Image vorhanden | Rettung nur, wenn Werks-Header intakt | Header aus Backup + Image = lesbar |
| Keyslot versehentlich gelöscht | Endgültig verloren | Header enthält alle Keyslots von damals |
0400, nicht in die Cloud, nicht auf den gleichen USB-Stick wie die Daten.
Debian-spezifisch: Das Paket cryptsetup-nuke-password (Version 8 in Debian 13)
verschlüsselt bei Eingabe eines zweiten, „Nuke“-Passworts den Header und macht die Daten unlesbar – für
Geräte, die verloren gehen können, eine bewusste Entscheidung.
Ohne Passphrase aufschließen: TPM2 und FIDO2
Auf Servern und Laptops mit TPM2 lässt sich die Passphrase durch Hardware binden – bequem (kein Tippen) und gefährlich (wer den Rechner hat, hat die Daten). systemd kann das direkt:
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/sdX
sudo systemd-cryptenroll --fido2-device=auto /dev/sdX # Sicherheitsschlüssel statt TPM
sudo systemd-cryptenroll --recovery-key /dev/sdX # Notfallschlüssel erzeugen
systemd-cryptenroll --list-devices 2>/dev/null || sudo systemd-cryptenroll /dev/sdX
| Variante | Komfort | Schutzwirkung |
|---|---|---|
| Passphrase | Niedrig (Tippen bei jedem Start) | Hoch – der einzige Faktor, den niemand „mitschicken“ kann |
| TPM2 mit PCR 0+7 (Firmware + Secure Boot) | Hoch | Mittel – schützt gegen entwendete Platte, nicht gegen Manipulation des Rechners im Betrieb |
| FIDO2-Sicherheitsschlüssel | Mittel (Stecken + PIN) | Hoch – Faktor ist physisch getrennt |
| Clevis/Tang (Netzwerk-Unlock) | Hoch für Serverflotten | Mittel – der Entsperrserver wird zur kritischen Infrastruktur (Arch: clevis 22, Debian: 20) |
systemd-cryptenroll und
cryptsetup zeigen beide Keyslots, die du dafür nutzt.
Nachträglich verschlüsseln
Ein bestehendes System lässt sich verschlüsseln, ohne Daten zu verlieren – aber nur mit Backups und Zeit. LUKS2 kann einen bestehenden Datenträger im laufenden Betrieb verschlüsseln („reencrypt“ mit Datenverschiebung), was bei einer halbvollen Platte Stunden dauern kann und einen Neustart übersteht nur begrenzt:
# Zustand ansehen: was passiert gerade?
sudo cryptsetup luksDump /dev/sdX | grep -A3 'Data segments'
# Neuen LUKS2-Header anlegen und bestehende Daten verschlüsseln (LUKS2-Reencryption)
sudo cryptsetup reencrypt --encrypt --type luks2 --reduce-device-size 32M /dev/sdX
# Fortschritt beobachten, Reencryption-Status abfragen
sudo cryptsetup luksDump /dev/sdX | grep -E 'online|reencrypt'
sudo cryptsetup reencrypt --resume-only /dev/sdX
| Weg | Aufwand | Risiko | Empfehlung |
|---|---|---|---|
| Neuinstallation mit LUKS | Neuaufsetzen + Daten zurück | Niedrig (sauberer Weg) | Für Systeme, die man ohnehin neu aufbaut |
In-place-Reencryption (cryptsetup reencrypt) | Stunden bis Tage, Stromausfall = Chaos | Mittel bis hoch | Nur mit vollständigem externem Backup und USV |
| Zweite Platte verschlüsselt, dann umziehen | Ein Abend | Niedrig | Der pragmatische Standard: neue Platte anlegen, rsync/Borg, umstecken |
| Nur Datenverzeichnis verschlüsseln (gocryptfs/rclone) | Minuten | Sehr niedrig | Wenn Betriebssystem und Bootloader unberührt bleiben sollen |
luksHeaderBackup,
danach luksDump prüfen – und ein Wiederherstellungstest auf einem zweiten Gerät.
Dateien und Ordner: gocryptfs, crypt, fscrypt
Oft braucht es keine ganze Platte: Ein einzelnes Verzeichnis soll verschlüsselt in eine Cloud oder auf einen USB-Stick – dort sind Dateinamen und Struktur schon Teil des Problems. Verzeichnisverschlüsselung arbeitet mit einem Klartext-Mount und einem Chiffrat-Verzeichnis:
| Werkzeug | Was es ist | Stärke | Schwäche |
|---|---|---|---|
gocryptfs | FUSE-Dateisystem, Go, ein Klartext-Mount auf ein Chiffrat-Verzeichnis | Schnell, einzeln abgesichert, ideal fürs Cloud-Verzeichnis (Arch 2.6.1 / Debian 2.5.1) | Größe der Dateien sichtbar; braucht FUSE |
cryfs | FUSE-Dateisystem mit Ziel „auch Metadaten verstecken“ | Verteilt Änderungen, schreibt immer ganze Blöcke um | Nur mit komplettem Chiffrat-Ordner umzuziehen (Arch 1.0.3 / Debian 0.11.4) |
rclone crypt | Verschlüsselungs-Layer vor jedem Cloud-Remote | Verschlüsselt Dateinamen, hält Aufbau mit rclone mount bequem | Nur über rclone nutzbar (Arch 1.75.1 / Debian 1.60.1) |
fscrypt | Native Verschlüsselung in ext4/f2fs, Kernel-seitig | Sehr schnell, kein FUSE; von Android/ChromeOS genutzt | Nur bestimmte Dateisysteme, Filenames nur mit Fallback-Encoding |
encfs | Der Klassiker von 2003 | Überall verfügbar | Historisch vorbelastet (Auth-Code-Leck) – heute nicht mehr empfehlen |
| VeraCrypt | Container-Dateien und ganze Platten, plattformübergreifend | Windows-Kompatibilität | In Debian 13 nicht in den Repos; auf dem Testsystem startete die GUI ohne Display nicht |
# Debian 13
sudo apt install gocryptfs
# CachyOS / Arch
sudo pacman -S gocryptfs
# Chiffrat-Ordner anlegen und initialisieren
mkdir -p ~/Cloud/chiffrat ~/klartext
gocryptfs -init ~/Cloud/chiffrat # Passphrase + Masterkey zweimal bestätigen
# Klartext mounten (bleibt bis unmount im Speicher verfügbar)
gocryptfs ~/Cloud/chiffrat ~/klartext
# Aufräumen: unmounten beendet den Klartextzugriff
fusermount3 -u ~/klartext
Für Cloud-Sync mit rclone ist der Aufbau derselbe, nur eine Ebene höher:
rclone config create cloud crypt remote=mein-remote filename_encryption=standard \
directory_name_encryption=true
rclone ls cloud: # zeigt entschlüsselte Namen
rclone ls mein-remote: # zeigt nur Chiffrat (unlesbar)
gocryptfs -init schreibt in den
Chiffrat-Ordner eine gocryptfs.conf (mit deiner Passphrase geschützt) und optional ein
Backup des Masterkeys (gocryptfs.conf.bak bzw. -masterkey-Ausgabe). Geht die
gocryptfs.conf verloren, hilft nur noch der Masterkey – also sicher wegkopieren, aber getrennt
vom Chiffrat.
Archive und Backups: 7z, age, GPG, restic
Auf dieser Ebene verlassen Daten das Haus – hier zählt, dass die Verschlüsselung authentifiziert ist (Manipulation fällt auf) und dass die Passphrase nicht im Skript steht. Die vier Kandidaten im Vergleich:
| Werkzeug | Verfahren | Authentifiziert? | Typischer Einsatz |
|---|---|---|---|
7z | AES-256 + Header-Verschlüsselung | Ja (Header verschlüsselt und authentifiziert) | Datenaustausch, Windows-kompatibel, große Archive |
age | ChaCha20-Poly1305, X25519-Schlüssel | Ja | Moderner Ersatz für gpg -c, einfache Schlüsseldateien (Arch 1.3.2 / Debian 1.2.1) |
| GPG | AES-256-CFB + SHA-512-S2K, optional MDC | Ja (mit MDC/Integritätsschutz) | Signatur und Verschlüsselung, Keyring-basiert, weit verbreitet |
restic / borg | Verschlüsseltes Repository mit eigenem Format (AEAD) | Ja | Backups: jede Datei einzeln verschlüsselt und dedupliziert (restic 0.19.1 / borg 1.4.5) |
openssl enc | AES-CBC + PBKDF2-Salt | Nein – CBC ohne MAC, Manipulation unbemerkt | Nur Übergangslösung; besser age/GPG verwenden |
# 7z: AES-256 mit verschlüsselten Dateinamen (-mhe=on)
7z a -p'SECRET' -mhe=on backup.7z ordner/
# Was steckt drin? (Listing braucht bei -mhe das Passwort)
7z l -slt -pSECRET backup.7z | grep -E '^(Path|Method|Encrypted)'
Path = backup.7z
Method = LZMA2:12 7zAES # Header
Path = klar.txt
Method = LZMA2:12 7zAES:19 # Datei
Encrypted = +
# Test mit falschem Passwort: klare Fehlermeldung statt Datenmüll
7z t -pFALSCH backup.7z
ERROR: backup.7z
Cannot open encrypted archive. Wrong password?
GPG ist der alte Standard und zeigt im Paketformat sehr schön, wie eine Passphrase-Verwaltung aussieht – hier eine echte symmetrische Verschlüsselung mit GnuPG 2.4.9:
gpg --symmetric --cipher-algo AES256 --pinentry-mode loopback --passphrase 'testpass' klar.txt
gpg --list-packets klar.txt.gpg
:symkey enc packet: version 4, cipher 9, aead 0, s2k 3, hash 10
salt FED63E48EFCAF08D, count 65536 (96)
:encrypted data packet:
| Feld im Paket | Bedeutung | Praxisrelevanz |
|---|---|---|
cipher 9 | AES-256 | Der Standard; GPG nennt es im Klartext „AES256.CFB verschlüsselte Daten“ |
s2k 3 | Iterated+Salted (Schlüsselableitung aus der Passphrase) | Ohne Salt könnten Rainbow-Tables greifen |
hash 10 | SHA-512 für die Ableitung | Zusammen mit count 65536 der Bremseffekt gegen Wörterbuchangriffe |
count 65536 | Anzahl der S2K-Durchläufe | Erhöhbar (--s2k-count) – kostet beim Öffnen Zeit, genau wie Argon2 2 s kostet |
aead 0 | Kein AEAD-Modus (klassischer CFB + Integritätsschutz) | Moderne AEAD-Verfahren vermeiden die Kategorie „Padding-Oracle“ von vornherein |
Und das Gegenbeispiel für die „mal schnell“-Fraktion – openssl enc funktioniert, ist aber nicht
authentifiziert:
openssl enc -aes-256-cbc -pbkdf2 -iter 200000 -salt -in klar.txt -out ssl.enc -pass pass:testpass
ls -la klar.txt ssl.enc
-rw-r--r-- 1 ba0 ba0 27 … klar.txt
-rw-r--r-- 1 ba0 ba0 48 … ssl.enc
# Rückweg
openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 -in ssl.enc -pass pass:testpass
Das ist ein Testgeheimnis.
openssl enc ist ein Werkzeug, kein Sicherheitskonzept. CBC ohne
Authentifizierung kann auf Bitmanipulation nicht reagieren, und die Passphrase steht bei Skripten schnell
im Klartext in der Zeile (siehe -pass). Für neue Dinge: age (Schlüsseldatei) oder
GPG (Keyring), für Backups restic/borg.
Schlüssel und Zugänge
Beim SSH-Schlüssel steckt die Verschlüsselung im Dateiformat – und sehr viele kennen nur den Teil bis zum `-t ed25519`. Das Testsystem zeigt, was wirklich im privaten Schlüssel steht (OpenSSH 10.5p1):
ssh-keygen -t ed25519 -a 100 -C 'test@huuu.biz' -N 'geheim' -f k_ed
ssh-keygen -l -f k_ed
256 SHA256:RozPBNrD0d3iYxoHvJYlouW6XQKGwB7BfvccpJhyi70 test@huuu.biz (ED25519)
stat -c 'Rechte: %a Größe: %s Bytes' k_ed
Rechte: 600 Größe: 444 Bytes
# Kopfdaten des openssh-key-v1-Formats ausgelesen:
Format : openssh-key-v1
Cipher : aes256-ctr
KDF : bcrypt
bcrypt : 100 Runden (ssh-keygen -a 100)
Salt : 2c4075f9a39b0186d5c507ca04fb08ee
| Detail | Bedeutung | Empfehlung |
|---|---|---|
aes256-ctr | Der private Schlüssel wird symmetrisch verschlüsselt abgelegt | Standard in OpenSSH, nicht änderbar – gut so |
bcrypt-KDF | Die Passphrase wird per bcrypt gestreckt, damit Brute-Force teuer ist | Genau deshalb hat ein Schlüssel mit Passphrase einen echten Mehrwert |
Runden: 100 statt 24 | Default in OpenSSH 10.x ist 24 Runden; -a 100 vervierfacht den Aufwand | -a 100 kostet beim Entsperren Millisekunden, beim Angriff Faktor 4 |
Rechte 600 | Nur der Eigentümer kann lesen – SSH verweigert sonst den Dienst | Rechte nie „reparieren“, sondern mit ssh-keygen -y prüfen |
# Neuer, moderner Schlüssel mit erhöhten KDF-Runden
ssh-keygen -t ed25519 -a 100 -C 'ich@example.org'
# Fingerprint zur Kontrolle auf dem Server (gegen MITM-Abwehr)
ssh-keyscan -t ed25519 server.example | ssh-keygen -lf -
# Agent nutzen, damit die Passphrase im Speicher bleibt statt im Verlauf
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519
Praxis: Swap, Container, Stick, Laptop
| Szenario | Richtig | Falsch / riskant |
|---|---|---|
| Swap auf einem verschlüsselten System | Swap-Partition ebenfalls per LUKS (Installer macht das mit) oder zram | Unverschlüsselter Swap: Auslagerungsdaten enthalten Passwörter im Klartext |
| Hibernation (Suspend-to-Disk) | Verschlüsselter Swap + Header, der Passphrase enthält | Hibernate in unverschlüsselten Swap = vollständiger RAM-Inhalt auf der Platte |
| Docker-Volumes auf einem Cloud-VPS | LUKS-Container als Volume, Schlüssel per Keyfile aus dem Boot-USB/TPM | Keyfile im gleichen Verzeichnis wie die Daten |
| USB-Stick für den Datentransport | LUKS-Container oder VeraCrypt-kompatibel (für Windows), Header-Backup getrennt | Nur Passwortgeschützte ZIPs – Namen und Struktur bleiben sichtbar |
| Laptop gestohlen | LUKS + TPM kombiniert mit Passphrase, Bildschirmsperre, kein Autologin | Verschlüsselung mit gespeicherter Passphrase in der initramfs |
| Backup auf ein NAS | restic/borg mit eigenem Repository-Key, Ziel unverschlüsselt egal | Vertrauen in die NAS-eigene „Verschlüsselung“ ohne Key-Backup |
| Kritische Secrets in Compose-Dateien | Docker-Secrets oder systemd-creds (auf beiden Distributionen vorhanden) | Passwörter in .env im Git-Repository |
# systemd-creds: Secrets an das System binden (kein Klartext in Dateien)
sudo systemd-creds encrypt --name=db-pass pass.txt /etc/credstore.encrypted/db-pass
# Docker: Secrets statt Umgebungsvariablen
docker secret create db_pass pass.txt 2>/dev/null || echo "Swarm-Modus: docker secret braucht einen Swarm"
Fehlerbild → Prüfbefehl
| Symptom | Prüfbefehl | Ursache/Umsetzung |
|---|---|---|
No key available with this passphrase | sudo cryptsetup luksDump /dev/sdX | Falsche Passphrase oder falscher Keyslot – Header prüfen, nicht raten |
| Gerät lässt sich nicht öffnen, Passphrase stimmt | sudo cryptsetup luksHeaderRestore … | Header beschädigt/überschrieben – nur ein Backup rettet jetzt |
| GRUB fragt nicht nach der Passphrase | sudo cryptsetup luksDump … | grep PBKDF | Keyslot nutzt Argon2id → auf PBKDF2 umstellen |
| Entsperren dauert Sekunden | cryptsetup benchmark | grep argon2 | Erwartetes Verhalten (Zieldauer 2 s) – kein Fehler |
Das Kernelmodul device-mapper kann nicht initialisiert werden | id -u | Kein root: Öffnen/Schließen braucht CAP_SYS_ADMIN – Header-Operationen nicht |
| Platte voll nach LUKS-Einrichtung | cryptsetup luksDump … | grep offset | 16 MiB Header-Bereich plus 4 KiB Sektoren sind normal |
| Archiv nicht öffenbar | 7z l -slt -p… archiv.7z | Bei -mhe=on sind auch die Namen verschlüsselt – Passwort ist Pflicht |
gpg: failed to start gpg-agent | gpgconf --kill gpg-agent; gpg --version | Agent/Berechtigungen des Home-Verzeichnisses (~/.gnupg muss 700 sein) |
Regeln für den Alltag
| Regel | Warum |
|---|---|
| Header/Key-Backup getrennt vom Datenbackup | Ein gestohlener Restore-Punkt mit Header ist ein Datenleck; ein Datenbackup ohne Header ist wertlos |
| Passphrasen mit 5+ Wörtern statt Zeichensalat | Argon2/bcrypt/S2K machen Rateversuche teuer, aber Länge schlägt Komplexität |
| Verschlüsselung in der Software, nicht im Zielsystem | Backup-Ziele und Cloud-APIs wechseln; die Verschlüsselung soll mitwandern |
| Ein Restore-Test pro Jahr | Nur ein getesteter Restore beweist Schlüssel, Tool und Passphrase |
| Keine selbstgebauten Verfahren | Verschlüsseln und dann komprimieren, ohne MAC, mit IV-Recycling – die klassischen Fehler entstehen hier |
| Krypto ist nicht die Schwachstelle | AES-XTS läuft mit 15,7 GB/s; Angriffe laufen über Passphrase, Header, Klartextkopien und Fehlkonfiguration |
Was hier nicht getestet wurde
Geprüft heißt: in dieser Umgebung selbst ausgeführt. Der Rest stammt aus Dokumentation und Paketquellen.
| Angabe | Status |
|---|---|
cryptsetup benchmark (alle Cipher- und PBKDF-Werte) | Direkt gemessen – CPU-werte des Testsystems (Ryzen 9 9950X3D), cryptsetup 2.8.7 |
/proc/crypto-Treiber (xts-aes-vaes-avx512) | Direkt gelesen |
LUKS2-Header anlegen, luksDump, luksAddKey, luksConvertKey, luksHeaderBackup, isLuks | Direkt ausgeführt – auf einer Datei, ohne root. Die Ausgaben im Artikel sind echt |
cryptsetup open / close (Gerät öffnen, mounten) | Nicht getestet – braucht CAP_SYS_ADMIN/root; die Fehlermeldung ohne root ist im Artikel zitiert |
Installer-Wege (Debian-Installer, Calamares) und Vollverschlüsselung inkl. /boot | Nicht getestet |
TPM2/FIDO2 (systemd-cryptenroll), Clevis/Tang, cryptsetup-nuke-password | Nicht getestet – kein TPM-Zugriff und keine root-Rechte; Befehle laut Dokumentation |
cryptsetup reencrypt (nachträgliche Verschlüsselung) | Nicht getestet – der Hinweis auf Backups ist entsprechend vorsichtig formuliert |
| GPG: symmetrische Verschlüsselung und Paketformat | Direkt geprüft (AES256.CFB, S2K iterated+salted, SHA-512, count 65536) |
| GPG: Schlüsselerzeugung und Entschlüsselung | Nicht möglich – gpg-agent ließ sich in der Testumgebung nicht starten |
| OpenSSH-Schlüsselformat (Cipher, bcrypt-Runden) | Direkt geprüft – eigene Auswertung des openssh-key-v1-Formats (100 vs. 24 Runden) |
| 7z mit AES-256 und verschlüsseltem Header | Direkt geprüft (inkl. Fehlermeldung bei falschem Passwort) |
openssl speed und openssl enc | Direkt gemessen bzw. ausgeführt (Roundtrip) |
gocryptfs, cryfs, fscrypt, rclone crypt, VeraCrypt | Nicht installiert/nicht ausgeführt – Befehle und Einschätzungen laut Dokumentation; VeraCrypt startete ohne Display nicht |
| Paketnamen und Versionen für Debian 13 und CachyOS | Aus den Distributionsquellen geprüft, nicht installiert |
Fazit
Verschlüsselung ist auf Debian und CachyOS kein Projekt, sondern eine Reihe kleiner Entscheidungen: LUKS2
für Datenträger (mit Header-Backup!), Verzeichnisverschlüsselung für das, was in die Cloud geht,
authentifizierte Archive (age, GPG, 7z) für alles, was das Haus verlässt, und Schlüssel, die
niemals neben ihren Daten liegen. Die Krypto selbst ist dabei das kleinste Problem: AES-XTS verschlüsselt
auf dem Testsystem mit 15,7 GB/s – schneller als jede NVMe. Teuer ist nur die Passphrase,
und genau das ist der Punkt, an dem Sicherheit entsteht.
1. Datenträger: LUKS2 (
aes-xts-plain64, Argon2id) – Header sofort sichern2. Boot-Partition mit GRUB: Keyslot auf PBKDF2 umstellen (
luksConvertKey)3. Server/Flotten: TPM2 oder Clevis zusätzlich zur Passphrase, nie ausschließlich
4. Cloud-Ordner:
gocryptfs (Dateisystem) oder rclone crypt (Sync)5. Backups/Archive: restic oder borg für laufende Backups,
age/7z für den Export – Schlüssel getrennt aufbewahren