dm-crypt/Luks – Begriffe, Funktionsweise und die Rolle des Hash-Verfahrens – II

Im letzten Post
dm-crypt/Luks – Begriffe, Funktionsweise und die Rolle des Hash-Verfahrens – I
bin ich auf ein paar wichtige Elemente und die Funktionsweise von LUKS eingegangen. Auf dieser Grundlage können wir uns nun ein paar Gedanken zum Einsatz von Hash-Verfahren - wie etwa SHA - im Rahmen von LUKS machen.

Folgendes hatten wir bereits herausgearbeitet:
Unter LUKS muss ein PBKDF-Verfahren aus einer beliebig langen Zugangs-Passphrase eine Byte-Sequenz definierter Länge berechnen. PBKDF steht dabei für "Password-based Key Definition Function"; konkret verwendet LUKS1 die Funktion PBKDF2 (RFC2898). Den Ergebnisstring von PBKDF2 hatte ich im letzten Beitrag "PB-Key" genannt. Bitte beachtet: "PB-Key" ist keine offizieller Begriff aus dem LUKS Wortschatz. Ich verwende den Begriff hier im Blog lediglich zur klaren Unterscheidung von anderen LUKS-Keys. Der PB-Key wird zur Ent-/Ver-Schlüsselung des sog. "Master-Keys" [MK] eingesetzt. Der Master-Key wird bei der Initialisierung eines LUKS-Devices zufällig erzeugt und später in einem symmetrischen Krypto-Verfahren zur Verschlüsselung der geheim zu haltenden Daten des Devices herangezogen. Der PB-Key ist im normalen Betrieb also nur ein Hilfsmittel, um den zentralen Master-Key zu ermitteln. Nichtsdestoweniger hängt die Sicherheit des Systems maßgeblich am PBKDF.

Das Erzeugen eines Strings definierter Länge (hier des PB-Keys) aus einem beliebig langen String (hier: der Passphrase) ist eine klassische Aufgabe von Hash-Algorithmen. Wir vermuten also (zu Recht!), dass LUKS im Rahmen des PBKDF Hash-Verfahren benutzen muss. Tatsächlich war das über lange Zeit default-mäßig SHA-1. Siehe etwa die Git-Hub-Dokumentation zu dm-crypt/Luks; unter dem Punkt 5 "Security Aspects" kann man dort lesen, dass LUKS standardmäßig SHA-1 einsetzt
(https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions).

Nun gilt aber SHA-1 schon seit längerer Zeit als unsicher. Deshalb findet man im Internet zahlreiche besorgte Diskussionen zum Einsatz von SHA-1 unter LUKS (s. die vielen Links am Ende des Artikels). Wie ist dieses Thema zu beurteilen? Diese Frage hat auch mich als Anwender beschäftigt - u.a. auch wegen der Anforderung der DSGVO, als Dienstleister im regelmäßigen Umgang mit personenbezogenen Daten Sicherheit auf dem Stand der Technik zu belegen. Ich hatte aber auch ein grundsätzliches Interesse an dem Thema.

Wo kommt das Hash-Verfahren in LUKS zum Tragen?

Unter LUKS wird ein vorab definierter Hash-Algorithmus im Rahmen des PBKDF2-Verfahrens eingesetzt. Das geschieht über ein sog. HMAC-Verfahrens und iterativ (s.u.). PBKDF2 ist aus Anwendersicht selbst ein komplexes Hash-Verfahren, das Keys in Form von Hashes erzeugt. LUKS generiert mit Hilfe von PBKDF2 aus (bis zu 8) Passwörtern (PB-Key-) Hashes für (bis zu 8) sog. Key-Slots. Diese Hashes werden aber nicht im System gespeichert. Ein PBKDF2-erzeugter Hash wird von LUKS nur eingesetzt, um den MK zu entschlüsseln oder bei Neuanlage eines Key-Slots auch zu verschlüsseln (s. den letzten Post).

PBKDF2 hat aber noch eine wichtige Aufgabe in LUKS: Es erzeugt einen (Vergleichs-) Hash für den (entschlüsselten) Master-Key - den sog. MK-Digest. Dieser "Digest" wird tatsächlich dauerhaft im "LUKS Partition Header" [PHDR] abgelegt und ist für die Funktionalität von LUKS unerlässlich, sobald man mehrere Key-Slots verwendet; siehe hierzu meinen letzten Blog-Post. Das ist übrigens ein Grund dafür, warum man den Hash-Algorithmus nur für das gesamte LUKS-Device und nicht für einzelne Slots definiert. Der MK-Digest dient aber nur zu einem Zweck: Als Vergleichs-Hash für die per PB-Key versuchsweise entschlüsselten Master-Key-Kandidaten der aktiven Slots. Er ist nicht direkt zur Ver- oder Entschlüsselung von irgendetwas brauchbar. Vielmehr setzt seine Nutzung logisch bereits eine korrekte Entschlüsselung des echten Master-Keys voraus.

Hash-Verfahren und Schwächen von SHA-1

Hash-Verfahren werden u.a. für die Erzeugung von Passwort-Hashes definierter Länge verwendet. In dieser Funktion sind sie vielen IT-Leuten, aber auch Anwendern bekannt. Linux-Distributionen nutzen zur Passwortbehandlung heute überwiegend SHA-512; die Ergebnisse kann man sich als root in der "/etc/shadow"-Datei ansehen. Ich werde gleich darauf zurück kommen, worin der Unterschied zum Einsatz in LUKS besteht. Hashes werden aber auch in Signatur- und Authentifizierungs-Verfahren eingesetzt - zusammen mit asymmetrischer Verschlüsselung (s.u.).

Hash-Algorithmen müssen die Anforderung erfüllen, dass sie auch mit hohem Aufwand nicht invertiert werden können; es soll auf vernünftigen Zeitskalen nicht möglich sein, aus dem Hash den Ursprungstext zu ermitteln. Jeder algorithmische Ansatz für eine Invertierung soll zumindest mehr Zeit kosten als ein Brute-Force-Angriff. Genau deshalb sind Hash-Verfahren auch keine (normalen) Verschlüsselungsalgorithmen; beim Erzeugen eines Hashes betritt man eine Einbahnstraße. Man kann mit verschiedenen Texten/Passwörtern erzeugte Hashes nur vergleichen. Für den sicheren Einsatz von Hash-Algorithmen spielt zudem der Punkte der Kollisionsfreiheit eine Rolle. Kollisionsfreiheit bezieht sich auf die Vermeidung oder statistische Unwahrscheinlichkeit von Situationen, in denen z.B. zwei oder mehr Passwörter zum selben Hash führen. Es soll auch nicht möglich sein, Kollisionsstrings mit algorithmischen Verfahren auf sinnvollen Zeitskalen zu berechnen.

In der Praxis trägt auch die benötigte CPU-Zeit des Hash-Berechnungsverfahrens wesentlich zur Sicherheit bei. Ist ein Verfahren auf modernen CPUs zu schnell darstellbar, kommt als typischer Angriffsvektor eine Brute-Force-Attacke in Frage: Dabei werden viele (gut) geratene Passwörter (z.B. auf Basis eines Wörterbuchs) mit hoher Geschwindigkeit in Hashes umgewandelt und getestet. Der Test kann in einem direkten Vergleich mit einem bereits bekannten String bestehen; er kann aber auch das Eingeben des Hashes in eine verarbeitende Anwendung erfordern. Um Rechenzeit zu sparen, kann man als Angreifer versuchen, die zu testenden Hashes vor einem Angriff in einer generell einsetzbaren (großen) Tabelle (Rainbow-Tabelle) zusammenzustellen. Man entkoppelt dabei den Rechenaufwand vom eigentlichen Angriffsprozess. Besonders effizient sind solche Angriffe, wenn es gelingt, den Ziel-Hash vom angegriffenen Computer zu entwenden - und man die generierten Hashes zum Testen nicht an weitere verarbeitende Anwendungsprozesse übergeben muss.

Man kann das Verfahren SHA-1 nun aus zwei Gründen als unsicher ansehen; nur der erste betrifft dabei die algorithmische Festigkeit (siehe https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html):

  • SHA-1 ist nicht kollisionsfrei genug. Es gibt effiziente algorithmische Ansätze, um Kollisionsstrings zu ermitteln. Ressourcen-starke Organisationen können bei Anwendung dieser Algorithmen genügend Rechenpower einsetzen, um zu bekannten Hashes Kollisions-Passwörter zu finden. Das wurde bereits demonstriert.
  • SHA-1 ist in der Praxis nicht CPU-intensiv genug; die Berechnung des 160-Bit umfassenden Hash-Outputs erfordert auf modernen CPUs/GPUs nur sehr geringe Zeit. Damit können extrem viele "Passwörter" in endlicher Zeit durchprobiert werden - im Besonderen auf GPUs.

Siehe hierzu auch Links am Ende des Beitrags.

Über die Bedeutung des zweiten Punkts kann man trefflich streiten. Es geht dabei nicht um ein Knacken durch Invertierung des algorithmischen Verfahrens; mir ist nicht bekannt, dass dies für SHA-1 je gelungen wäre. Es geht eher um Brute-Force-Angriffe. In der Praxis von Hackern, die Passwörter knacken wollen, ist dieser Punkt deshalb durchaus relevant; je mehr Passwörter man in kurzer Zeit mit Tools wie JtR oder Hashcat durchprobieren kann, desto besser ist es aus Sicht des Hackers. Die Sicherheit hängt unter solchen Bedingungen auch stark an der Zufälligkeit der Zeichenwahl für das Passwort. Im realen Leben verwenden die meisten Anwender aber keineswegs hinreichend zufällige Passwörter genügender Länge (und Entropie). Die Chance durch geschicktes und sprachspezifisches Raten auf ein einfaches Passwort zu stoßen, sind entsprechend hoch. Das Thema relativiert sich für SHA-1 aber dadurch, dass modernen CPUs SHA-256 und SHA-512 gut unterstützen. Z.T. erfolgen die Berechnungen sogar effizienter als von SHA1. Die Lösung bzgl. des Problems kurzer CPU-Zeiten besteht daher nicht nur für SHA-1 in einer künstlichen Verlängerung des Erzeugungsprozesses für den Hash (Stretching; s.u.).

Es ist bei SHA-1 vor allem aber der zweite Punkt, der als kritisch bewertet wurde - mit erheblichen Auswirkungen für die elektronische Kommunikation im Internet. Der Grund war der, dass SHA-1-Hashes vielfach für die Erstellung von Signaturen, die zum Nachweis elektronischer Identitäten dienen, eingesetzt wurde. Solche Signaturen spielen im Besonderen bei der Prüfung der Identität von Web-Servern und Web-Domänen eine Rolle. Hier geht es dem Angreifer darum, einen bekannten Hash (Signatur) aus einem zu eigenen String/Text zu produzieren, der nicht mit dem Original-String/Text (z.B. einem Zertifikat) identisch ist. In der Praxis kommen zum Nachweis der Identität zwar auch unabhängige Institutionen und asymmetrische Kryptierung ins Spiel; aber da kann der Angreifer ggf. tricksen. Ich verdeutliche das, um klar zu machen, wie wenig diese Schwäche sich auf eine Manipulation von LUKS übertragen lässt:

Ein Client (z.B. ein Browser), der die Identität eines Web-Servers prüfen will, prüft einen vom Server übermittelten sog. Zertifikatsstring, indem er dessen Hash mit einem, von einer Beglaubigungsinstitution (Certification Authority; CA) kryptierten Hash (Signatur) vergleicht. Die CA hat dazu das originale Zertifikat zuvor selbst gehasht und mit Hilfe des privaten Schlüssels eines asymmetrischen Krypto-Verfahrens kryptiert. Das Ergebnis ist die Signatur, die dem Zertifikat als separate Information angefügt wurde. Der Client ermittelt den Hash des Zertifikats über einen vorgegebenen Hash-Algorithmus. Dann entschlüsselt er die "Signatur" mit dem öffentlichen Schlüssel der CA - und vergleicht den so erhaltenen Hash-Wert mit dem selbst ermittelten. Im positiven Fall ist die Identität verifiziert. Kann man nun als Angreifer auf Basis eines Kollisions-Strings ein Fake-Zertifikat produzieren, das denselben Hash produziert (Kollision), muss man es nur noch von einer (schlampigen) CA signiert bekommen und dem Client an passender Stelle unterjubeln. Das war/ist im Kern das Problem mit SHA1-basierten SSL-Zertifikaten. Das Entscheidende an dieser SHA1-Schwäche ist, dass der Hash bekannt sein muss - und man mit großer CPU-Power wie Spezialalgorithmen Kollisionsstrings ermittelt haben muss.
Siehe:
https://konklone.com/post/why-google-is-hurrying-the-web-to-kill-sha-1
http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art012

In einigen Foren im Internet wurde nun die Frage aufgeworfen, ob diese Schwächen nicht auch irgendwie auf LUKS durchschlagen. Siehe hierzu Links unten.

Schlagen die Schwächen von SHA-1 auf LUKS durch?

Ich tendiere dazu, diese Frage mit Nein zu beantworten. Das beruht auf 4 Überlegungen; die ersten beiden gelten dabei unabhängig vom Hash-Algorithmus:

  • Argument 1: Der Hash, der in LUKS als Key zur Entschlüsselung des Master-Keys benutzt wird, wird nirgendwo im System hinterlegt! Er wird lediglich zwischenzeitlich berechnet und in einem weiteren (symmetrischen) Verfahren als Key zur De-Kryptierung eines später zur eigentlichen Datenverschlüsselung genutzten Schlüssels eingesetzt. Insofern ist der Hash einem Angreifer (natürlich) auch nicht bekannt. Das macht bestimmte Angriffsverfahren von vornherein irrelevant.
  • Argument 2: Der im Rahmen des LUKS-Verfahrens berechnete Hash beruht nicht auf einer einmaligen Anwendung von SHA. Das PBKDF2-Verfahren ist deutlich komplexer: Es verwendet SHA im Rahmen eines HMAC-Verfahrens unter Einschluss von Salting - und es arbeitet vor allem iterativ. Durch Hunderttausende oder Millionen von Iterationen wird die Zeit für eine PB-Key-Berechnung in den Bereich von Sekunden erhöht. 256-Bit Salts wirken dem Erstellen von vorberechneten Tabellen entgegen. Die Kombination aus Komplexitätserhöhung, Verlängerung von Passwörtern und Iterationen wird auch als Passwort-Stretching bezeichnet.
  • Argument 3: Seit LUKS-Version 1.7.x wird SHA-256 als Default genutzt. Für neuere Installationen ist die Debatte irrelevant.
  • Argument 4: Eine schwache Passphrase bleibt eine schwache Passphrase - egal wie gut ein Hash-Verfahren ist. Man kann diese Schwäche nur teilweise durch Erhöhung des Rechenaufwands und durch Salts kompensieren.

Ich erläutere diese Punkte nachfolgend.

Der Hash zu den PB-Keys ist dem Angreifer nicht bekannt und nicht hinterlegt

Diesen Punkt hatten wir bereits im letzten Blog-Beitrag herausgearbeitet. Er zementiert nur, dass es bei Angriffen auf LUKS nicht um die Invertierung eines dem Angreifer bekannten Hashes geht. Das ist ganz anders als bei Angriffen auf erbeutete Passwort-Hashes eines Betriebssystems. Ein testweise berechneter Hash muss unter LUKS vielmehr in einem direkten nächsten Schritt zwingend in ein Dekryptierungsverfahren eingebracht und nicht mit einem bekannten String verglichen werden. Siehe hierzu: https://unix.stackexchange.com/questions/101398/why-does-luks-need-to-generate-hash-values).

Würde der Angreifer den unter LUKS erzeugten Hash (PB-KEY) in Erfahrung bringen (z.B. durch einen Dump des RAM), wäre sowieso schon alles verloren (siehe den letzten Beitrag). Der Witz ist ja gerade, dass der Hash nur temporär berechnet und zur Invertierung des Master-Keys eingesetzt wird. Angriffsvektoren, bei denen erzeugte Hashes mit einem bekannten Hash verglichen werden könnten, stehen im Zusammenhang mit LUKS so gar nicht zur Debatte. Ein Vergleich mit Angriffen auf Passwort-Listen hinkt schon aus logischen Gründen!

Man könnte nun noch auf den Gedanken kommen, dass ein Bruch der Kollisionsfreiheit evtl. dazu genutzt werden könnte, den Master-Key-Digest auszutauschen. Das käme jedoch einem Ersatz des (entschlüsselten) Master-Keys gleich und hätte im Rahmen des symmetrischen Verschlüsselungsverfahrens keinen Sinn. Auch bei einer zugehörigen Manipulation des PB-Keys lässt sich daraus aus meiner Sicht kein sinnvoller Angriff konstruieren. Ein destruktiver Angriff könnte den Master-Key tatsächlich ersetzen. Umso wichtiger sind Backups des PHDR.

Angriffe, die auf Daten-Entschlüsselung abzielen, müssen sich eher dem intelligenten Raten der Passphrase oder dem direkten Abfangen des erzeugten PB-Keys widmen. Dem ersten Angriff wirkt Stretching (s.u.) entgegen. Bzgl. des zweiten Weges gilt: Der Angreifer muss darauf setzen, auf irgendeine illegale Weise den RAM für den cryptsetup-Prozess auszulesen. Das kann einerseits über ein Hacken des Systems auf dem LUKS läuft voraus; ein gehacktes System hat aber sowieso mit einer Vielzahl von Problemen zu kämpfen. Der Schutz des RAMs betrifft aber auch so illustre Punkte wie: Auslesbare RAM-Fragmente nach einem Shutdown; Zugriff während Sleep-Phasen und im Vorfeld von Hibernating; keine hinreichende Abgrenzung prozess-spezifischer RAM_Bereiche auf Virtualisierungshosts; Schwächen von CPUs in der RAM-Behandlung (Spectre, Meltdown).

SHA kommt in HMAC-Form zum Einsatz

SHA wird nicht direkt sondern in ein komplexeres, sog. "HMAC"-Verfahren eingebunden. Ich kann in diesem Beitrag nicht auf Details von HMAC-Funktionen eingehen. Siehe aber: https://en.wikipedia.org/wiki/HMAC. HMAC-Funktionen benutzen zwar Hash-Algorithmen und erzeugen wie diese Hashes; eine HMAC-Funktion verkompliziert das Hashing jedoch durch mehrere eingeschobene Operationen deutlich. HMAC-Funktionen sind zudem weniger anfällig gegen Kollisionen als der zugrunde liegende Hash-Algorithmus selbst. Das liegt an einer zwischenzeitlichen Aufbereitung des Passworts mit anschließender Splittung nach definierten Regeln, erneuter Konkatenierung und Ergänzung mit einem Salt vor einer finalen Anwendung der Hash-Funktion. Dass HMAC-Verfahren durch die Schwächen von SHA1-1 nicht direkt betroffen sind, stellt z.B. auch Bruce Schneier fest: "SHA-1 Broken".

Hinweis für Interessierte:
Die Frage was PBKDF2 in das "HMAC-SHA"-Verfahren als "Key" und was als "message" einfüttert, wird hier beantworte: .
https://crypto.stackexchange.com/questions/10164/pbkdf2-uses-hmac-sha1-to-generate-keys-but-what-is-the-key-for-the-hmac
Siehe auch: http://www.ietf.org/rfc/rfc2898.txt
Die LUKS-Passphrase wird also als "Key", das Salt als "message" benutzt.

Stretching - PBKDF2 kostet Zeit und Rechenpower

Der Clou an PBKDF2 ist für mich die Iteration des HMAC-SHA-x Verfahrens; die erneute iterative Anwendung geschieht nicht ein paar Mal. Auf modernen PC-CPUs erfolgt die Iteration vielmehr mehrere hunderttausende Male, ggf. mehrere Millionen Mal. Hierfür gibt es einen Parameter:

Key = PBKDF2(hash_function, passphrase, salt, iterations, KeyLen)

Faktisch wird Anzahl der Iterationen beim Setup eines LUKS-Devices aus der als Options-Parameter (--iter-time) übergebenen Länge eines gewünschten Zeitintervalls (in msec) bestimmt. Es dauert dann die vorgegebene Zeit (z.B. 2 Sekunden), bevor PBDKF2 den finalen Hash - also den von Luks dann weiter verwendeten PB-Key - ausspuckt. Das Kommando "cryptsetup benchmark" erlaubt einen Test - nachfolgend für eine i7-6700K CPU:

mytux:~ # cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1      1002462 iterations per second for 256-bit key
PBKDF2-sha256    1416994 iterations per second for 256-bit key
PBKDF2-sha512    1219274 iterations per second for 256-bit key
PBKDF2-ripemd160  814111 iterations per second for 256-bit key
PBKDF2-whirlpool  782519 iterations per second for 256-bit key
argon2i      12 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id     12 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
....

Die Zahlen verdeutlichen, warum PBKDF2 etwas mit Stretching zu tun hat!

Hinweis:
Man sollte diesen Test speziell auf langsamen CPUs vor der Anlage eines LUKS-Devices durchführen - und erst dann die Zeit (cryptsetup- Option "--iter-time" oder "-i") festlegen. Wichtig ist am Ende weniger die benötigte Zeit als vielmehr eine hohe Anzahl an Iterationen! Das gilt unabhängig vom Hash-Algorithmus! Die Iterationszahl sollte man dabei wohl eher an schnellen Systemen ausrichten. Das ist im besonderen wichtig, wenn man einen Laptop aufsetzt. Ein Angreifer, der den Laptop gestohlen hat, wird die LUKS-Partitionen eher mit anderen Systemen als dem Laptop selbst analysieren. Also seht euch diesen Test auch mal auf anderen Systemen (PCs, Server) an, bevor ihr euch für eine iter-time und damit indirekt für eine Iterationszahl entscheidet. Mir selbst scheint aktuell eine Zahl > 1000000 Iterationen sinnvoll. Siehe auch:
https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pkbdf2-sha256
Die cryptsetup Option "--iter-time" oder "-i" kann übrigens für jeden neuen Key-Slot (Option -S) separat gewählt werden. ($ sudo /sbin/cryptsetup luksAddKey -S 6 -h sha512 -s 512 -i 3000 /dev/sdx)

Warum kann man als LUKS-Awender die benötigte PBKDF2-Zeit in den Bereich von Sekunden zwingen? Weil man diese Zeit nur einmal beim Öffnen des LUKS-Devices investieren muss. Ein Angreifer muss diese Zeit aber viele, viele Male investieren. Unter folgendem Link findet man eine Tabelle zum Zusammenhang zwischen Password-Stärke, Interationen und Aufwand mit Hashcat als Cracking Tool auf GPUs:
https://support.1password.com/pbkdf2/

Hinweis:
Auch für die Erzeugung des MK-Digest muss man natürlich eine PBKDF2-Iterationszahl festlegen. Diese ist unabhängig von entsprechenden Parametern für die Key-Slots und wird deshalb auch im Hauptteil des LUKS-Partitions-Headers hinterlegt. Man legt die Iterationszahl auch hier indirekt über den Parameter "iter-time" fest, den man beim Aufruf von "cryptseup luksFormat" übergibt.

Vorberechnete Tabellen?

Ein Angreifer, der in Besitz eines LUKS-Devices kommt, kann den PHDR und auch die "Key material Sections" mit den verschlüsselten Master-Key-Daten auslesen (s. den letzten Post). Damit sind ihm auch das symmetrische Verschlüsselungsverfahren, das Hash-Verfahren, Salt sowie Anzahl der Iterationen bekannt. Nun könnte er Rainbow-Tabellen vorbereiten, um sich im Angriffsszenario der Last der PBKDF2-Berechnung zu entziehen und Hashes direkt an das symmetrische Verschlüsselungsverfahren übergeben. Er muss den Rechenaufwand für PBKDF2 natürlich aber vorab aufbringen. Sein Problem ist dabei aber das Salting - um eine generell einsetzbare Tabelle zu erstellen, müsste er vorab auch alle möglichen Salt-Strings (für 256 Bit) in Kombination mit allen zu testenden Passwörtern (z.B. aus einem Wörterbuch) in PBKDF2 einfüttern. Damit sind für einen generellen Einsatz aber wahrlich gigantische Tabellen erforderlich. Ein Angreifer wird solche Tabellen also erst vorbereiten, wenn er den Salt-String kennt - also nach dem Diebstahl. Dann allerdings ist er immer noch mit der Zeitdauer des PBKDF2-Verfahrens konfrontiert.

Ist der Standard wirklich noch SHA-1?

Das hängt davon ab, mit welcher Version von LUKS ihr operiert. Ich bin auch nicht sicher, ob das distributionsabhängig ist. Man sollte es lieber prüfen. Dazu hilft "cryptsetup --help":

mytux:~ # cryptsetup --help
Default compiled-in key and passphrase parameters:
        Maximum keyfile size: 8192kB, Maximum interactive passphrase length 512 (characters)
Default PBKDF2 iteration time for LUKS: 2000 (ms)
Default PBKDF for LUKS2: argon2i
        Iteration time: 2000, Memory required: 1048576kB, Parallel threads: 4

Default compiled-in device cipher parameters:
        loop-AES: aes, Key 256 bits
        plain: aes-cbc-essiv:sha256, Key: 256 bits, Password hashing: ripemd160
        LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha256, RNG: /dev/urandom

Das sieht so aus, als ob SHA-256 inzwischen der Standard ist. Siehe auch:
https://security.stackexchange.com/questions/131035/are-default-options-of-cryptsetup-luks-secure
https://security.stackexchange.com/questions/39306/how-secure-is-ubuntus-default-full-disk-encryption
Ich würde mir dennoch grundsätzlich angewöhnen, den Algorithmus beim Anlegen eines LUKS-Devices selbst festzulegen. Bitte beachtet, dass der Hash-Algorithmus für das Device insgesamt festgelegt werden muss - und nicht pro Slot.

Zugegeben, dieser Punkt nützt Leuten, die ihre Daten bereits auf einem LUKS-Device haben, das mit SHA-1 konfiguriert wurde, wenig, wenn kein kompletter Umzug und Neuaufbau betrieben werden soll.

Passphrase-Qualität

Zuletzt hängt alles an der Qualität der Passphrase. Verwende ich eine Passphrase wie "Esel", muss ich mich nicht wundern, wenn meine Verschlüsselung trotz Stretching in endlicher Zeit gebrochen wird. Egal, wie gut mein Hash-Verfahren ist. Das führt zur Frage, wie lang und gut eine Passphrase für LUKS eigentlich sein sollte. Dazu findet man interessante Überlegungen in folgendem Artikel für die Kombination dm-crypt/Luks:
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions
Der Autor kommt zum Schluss:

LUKS: Use > 65 bit. That is e.g. 14 random chars from a-z or a random English sentence of > 108 characters length. If paranoid, add at least 20 bit. That is roughly four additional characters for random passphrases and roughly 32 characters for a random English sentence.

Die Bit-Anzahl misst dabei die statistische Zufälligkeit. 108 Buchstaben in einem zufälligen englischen Satz sind eine ganze Menge Wörter. Man kann die Entropie aber durch Mixen von sinnlosen Wörtern mit angereicherten Elementen erhöhen, sowie Wörter aus verschiedenen Sprachen mischen. Ein anderer Autor kommt zu Ergebnissen, die freundlicher für den Benutzer aussehen:
http://canonical.org/~kragen/cryptsetup

It is reasonable to memorize a phrase of six 5-letter-or-less words chosen from among the 4096 most common words in English. They provide 72 bits of entropy, and LUKS can provide 16 bits of key stretching, for a total of 288 PBKDF2 iterations to exhaust the entire keyspace. A brute-force attack then would require a computational expense currently equal to half a century of world economic output.

Ich empfehle, Wörter aus verschiedenen Sprachen in sinnlosen Sätzen zu mischen - und mit willkürlichen Zahlen/Trennzeichen anzureichern. Dabei sollte man Umlaute vermeiden und auch bzgl. der Trennzeichen auf mögliche wechselnde Tastatur-Layouts aufpassen!

Was sagt die cryptsetup-Doku zur SHA-1-Thematik?

In der Github Doku zu "cryptsetup" liest man unter Punkt "5.20 LUKS is broken! It uses SHA-1!":

No, it is not. SHA-1 is (academically) broken for finding collisions, but not for using it in a key-derivation function. And that collision vulnerability is for non-iterated use only. And you need the hash-value in verbatim.
This basically means that if you already have a slot-key, and you have set the PBKDF2 iteration count to 1 (it is > 10'000 normally), you could (maybe) derive a different passphrase that gives you the the same slot-key. But if you have the slot-key, you can already unlock the key-slot and get the master key, breaking everything. So basically, this SHA-1 vulnerability allows you to open a LUKS container with high effort when you already have it open.

Mein Fazit

Insgesamt sollte man wegen SHA1 aus meiner Sicht nicht in Panik verfallen. Dazu gibt es (noch) keinen Grund. Auf einem aktuellen System wird das sowieso nicht mehr als Default verwendet. Wer bzgl. vorhandener LUKS-Devices, die noch SHA-1 nutzen, paranoid ist, hat zwei Möglichkeiten:

  • Den gesamten Daten-Inhalt in ein Backup überführen. Das LUKS-Device mit anderen Parametern neu aufbauen und aus dem Backup füllen.
  • Mühe in gute Passphrases investieren und diese dann systematisch für bestehende Key-Slots austauschen. Dabei auch die Iterationszeit ( und -anzahl) für PBKDF2 anpassen. Das geht nämlich pro Slot.

Dennoch gibt es aus meiner Sicht auch keinen guten Grund, bei neu anzulegenden LUKS-Devices nicht SHA-256 oder gleich SHA-512 zu verwenden. Im Schadensfall wird ein Kunde uns Freelancer womöglich mit Berufung auf die DSGVO auf den ominösen "Stand der Technik" fixieren wollen; deshalb fährt man mit SHA-512 sicher auch aus rechtlicher Perspektive besser. Also:

cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 3000 -v luksFormat /dev/YOURDEVICENAME

Ich werde die praktische Anwendung der gewonnenen Erkenntnisse in weiteren Posts darstellen. Da geht es dann um das Aufsetzen eines Laptops unter Opensuse Leap 15. Bis dann ....

Links


Irreversibilität von Hash-Algorithmen?

https://security.stackexchange.com/questions/11717/why-are-hash-functions-one-way-if-i-know-the-algorithm-why-cant-i-calculate-t

Schwäche von SHA1
https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html
https://konklone.com/post/why-google-is-hurrying-the-web-to-kill-sha-1
https://www.computerworld.com/article/3173616/security/the-sha1-hash-function-is-now-completely-unsafe.html
https://www.tbs-certificates.co.uk/FAQ/en/sha256.html
https://www.schneier.com/blog/archives/2005/02/sha1_broken.html
https://stackoverflow.com/questions/38038841/why-is-sha-1-considered-insecure
http://2012.sharcs.org/slides/stevens.pdf

https://stackoverflow.com/questions/3740443/how-insecure-is-a-salted-sha1-compared-to-a-salted-sha512

SHA1 und HMAC
https://crypto.stackexchange.com/questions/26510/why-is-hmac-sha1-still-considered-secure
https://np.reddit.com/r/Ubuntu/comments/3m4saj/ubuntuserver_installer_is_using_weak_hash/
https://cseweb.ucsd.edu/~mihir/papers/kmd5.pdf

Kollisionen als "Kuriosität" im HMAC-Umfeld
https://mathiasbynens.be/notes/pbkdf2-hmac
https://crypto.stackexchange.com/questions/15218/is-pbkdf2-hmac-sha1-really-broken

SHA1 in LUKS oder Veracrypt unsicher?
https://sourceforge.net/p/veracrypt/discussion/general/thread/82add23d/
https://security.stackexchange.com/questions/79240/about-sha1-in-default-disk-encryption-in-linux
https://ubuntuforums.org/showthread.php?t=1170405
https://ubuntuforums.org/showthread.php?t=2260677
https://security.stackexchange.com/questions/131035/are-default-options-of-cryptsetup-luks-secure
https://security.stackexchange.com/questions/79008/security-of-linux-full-disk-encryption-ubuntu-mint-insecure
https://security.stackexchange.com/questions/131035/are-default-options-of-cryptsetup-luks-securehttps://security.stackexchange.com/questions/79240/about-sha1-in-default-disk-encryption-in-linux
http://hideandhack.blogspot.com/2013/05/do-not-use-sha-1-luks-disk-encryption.html
https://security.stackexchange.com/questions/39306/how-secure-is-ubuntus-default-full-disk-encryption
https://www.wilderssecurity.com/threads/hardening-generic-luks-from-common-distro-installs.389776/

https://www.reddit.com/r/crypto/comments/3m4maq/why_ubuntuserver_installer_is_using_sha1_instead/
https://np.reddit.com/r/Ubuntu/comments/3m4saj/ubuntuserver_installer_is_using_weak_hash/

Beispiel mit teilweise falscher Antwort
https://unix.stackexchange.com/questions/254017/how-to-interpret-cryptsetup-benchmark-results
(In the answer it is claimed that the hash of the user's password is stored)

PBKDF2
https://en.wikipedia.org/wiki/PBKDF2
https://support.1password.com/pbkdf2/
http://www.ietf.org/rfc/rfc2898.txt
https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
https://security.stackexchange.com/questions/133239/what-is-the-specific-reason-to-prefer-bcrypt-or-pbkdf2-over-sha256-crypt-in-pass
https://stackoverflow.com/questions/23946349/for-pbkdf2-using-hmac-sha256-is-more-secure-than-using-hmac-sha-1

SHA512 Empfehlung
https://security.stackexchange.com/questions/40208/recommended-options-for-luks-cryptsetup

Key Stretching
https://unix.stackexchange.com/questions/101398/why-does-luks-need-to-generate-hash-values

Missverständnisse bzgl. des Hashes und Luks
https://unix.stackexchange.com/questions/101347/how-can-i-extract-the-hash-value-of-a-luks-device
https://forums.gentoo.org/viewtopic-t-980544-start-0.html
https://crypto.stackexchange.com/questions/24022/luks-multiple-key-slots-whats-the-intuition
https://security.stackexchange.com/questions/79240/about-sha1-in-default-disk-encryption-in-linux

Cryptsetup-Parameter
https://advanced-analytica.com/2018/04/06/data-security-on-linux/

Rainbow Tables
https://en.wikipedia.org/wiki/Rainbow_table

Argon2
https://password-hashing.net/