Timing-Angriffe in Code auf Anwendungsebene
Lernen Sie, wie das Timing von String-Vergleichen Geheimnisse preisgibt und wie zeitkonstante Vergleiche dies verhindern.
Timing-Angriffe in Code auf Anwendungsebene ist eine kostenlose Cryptology Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Cryptology Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Cryptology Academy-Kurs umfasst insgesamt 4 Lektionen.
Stringvergleich nicht in konstanter Zeit
Der Standardoperator für String-Gleichheit beendet den Vergleich in den meisten Programmiersprachen, sobald eine Abweichung gefunden wird. Pythons == für Bytes-Objekte, C's strcmp und Javas String.equals geben sofort zurück, sobald das erste unterschiedliche Byte gefunden wird. Bei einem normalen Stringvergleich ist dies eine Optimierung. Beim Vergleich geheimer Werte wie MAC-Tags oder Passwörter entsteht dadurch jedoch ein messbarer Timing-Seitenkanal, der Informationen preisgibt.
Zeit für HMAC-Vergleiche messen
Ein Angreifer misst die Zeit, die benötigt wird, um einen übermittelten HMAC-Tag mit dem korrekten Wert zu vergleichen. Die Übermittlung eines HMAC, bei dem das erste Byte korrekt übereinstimmt, dauert geringfügig länger als bei einem HMAC mit einem falschen ersten Byte, da ein zusätzliches Byte verglichen wird. Indem der Angreifer viele Werte mit jedem möglichen ersten Byte übermittelt und die Antwortzeiten misst, ermittelt er das korrekte erste Byte. Dieser Vorgang wird Byte für Byte wiederholt, bis der vollständige Tag rekonstruiert ist.
Praktische Präzision von Timing-Angriffen
Moderne Timing-Angriffe über Netzwerke können Zeitunterschiede von einigen Dutzend bis einigen Hundert Nanosekunden über das Internet auflösen. Ein 32-Byte-HMAC-Vergleich, bei dem jedes korrekte Byte etwa 10–100 ns zusätzliche Verarbeitungszeit verursacht, liefert nach genügend wiederholten Messungen ein messbares Signal, über das sich das Netzwerk-Jitter herausmitteln lässt. In einem lokalen Netzwerk können bei ausreichender statistischer Stichprobenerhebung sogar Unterschiede von einzelnen Nanosekunden ausgenutzt werden.
Sicherheitslücke durch den ==-Operator in Python
In Python ist der Vergleich von MAC-Tags mit == unsicher: Der Vergleich mac == submitted_mac liefert True oder False, abhängig von der Position der ersten Abweichung. Ein Angreifer kann durch die Übermittlung von Tausenden gezielt erstellten Tags und die Messung der Antwortzeiten den erwarteten Tag Byte für Byte rekonstruieren. Diese Sicherheitslücke ist in produktiven Webanwendungen aufgetreten, die den Vergleich von Sitzungstoken oder API-Schlüsseln ohne Funktionen für Vergleiche in konstanter Zeit fehlerhaft implementiert hatten.
hmac.compare_digest in Python
Python-Implementierung hmac.compare_digest(a, b) vergleicht zwei Byte- oder String-Werte in konstanter Zeit. Dabei wird unabhängig davon stets gleich viel Zeit benötigt, an welcher Stelle die erste Abweichung auftritt. Die Funktion ist in C implementiert, um auch unter dem zusätzlichen Overhead der Interpretation von Python-Bytecode ein Verhalten in konstanter Zeit sicherzustellen. Verwenden Sie für den Vergleich von MAC-Tags, Sitzungstoken, API-Schlüsseln oder anderen Werten, bei denen Zeitinformationen gefährlich wären, immer hmac.compare_digest.
CRYPTO_memcmp in OpenSSL
OpenSSL stellt CRYPTO_memcmp(a, b, length) für Speichervergleiche in konstanter Zeit bereit. Anders als memcmp verarbeitet die Funktion immer alle length Bytes, unabhängig von frühen Abweichungen. Der Rückgabewert ist null, wenn die Werte gleich sind, und ungleich null, wenn sie sich unterscheiden. Es ist wichtig, immer die vollständige erwartete Länge zu vergleichen: Der Vergleich unterschiedlich langer Werte nur bis zur kürzeren Länge kann weiterhin Informationen über die Länge preisgeben. Verwenden Sie CRYPTO_memcmp in C/C++-Code mit OpenSSL für jeden sicherheitskritischen Vergleich.
Timing-Angriffe auf RSA: Bleichenbacher
Timing-Angriffe gehen über den Vergleich von Zeichenfolgen hinaus. Bleichenbachers Angriff von 2006 auf die Entschlüsselung mit RSA PKCS#1 v1.5 demonstrierte ein praktisches Timing-Orakel gegen SSL/TLS-Implementierungen. Die Laufzeit der RSA-Operation mit dem privaten Schlüssel variierte abhängig davon, ob der entschlüsselte Wert über ein gültiges PKCS#1-Padding verfügte. Durch die Übermittlung Tausender gezielt erstellter Chiffrate konnten Angreifer private RSA-Schlüssel rekonstruieren. Dies führte zur Entwicklung von RSA-OAEP und RSA-Implementierungen mit Laufzeit in konstanter Zeit.
Cache-Timing-Angriffe auf AES
AES-Implementierungen, die Nachschlagetabellen verwenden (aus Performancegründen weit verbreitet), greifen abhängig vom Schlüssel und Klartext auf unterschiedliche Tabelleneinträge zu. Cache-Treffer und Cache-Fehlzugriffe erzeugen messbare Zeitunterschiede, aus denen sich ableiten lässt, auf welche Tabelleneinträge zugegriffen wurde. Dieser Seitenkanal kann AES-Schlüssel offenlegen. Die Abhilfe besteht darin, AES-Implementierungen zu verwenden, die nicht auf Tabellenzugriffe angewiesen sind, etwa AES-NI-Hardwarebefehle oder Bit-Slicing-Softwareimplementierungen.
Prinzipien für Implementierungen mit konstanter Laufzeit
Für Code mit konstanter Laufzeit müssen Sie Folgendes vermeiden: bedingte Verzweigungen abhängig von geheimen Daten (verwenden Sie eine verzweigungsfreie Auswahl mit Maskierung), Speicherzugriffsmuster, die von geheimen Daten abhängen (vermeiden Sie Nachschlagetabellen, deren Index aus Geheimnissen abgeleitet wird), sowie Operationen, deren Latenz von geheimen Werten abhängt (beispielsweise Division auf manchen Prozessoren). Compiler können Konstrukte für konstante Laufzeit wegoptimieren. In kritischen Abschnitten können daher Assemblercode oder volatile Speicherzugriffe erforderlich sein.
AEAD macht den MAC-Vergleich auf Anwendungsebene überflüssig
Die beste Abwehr gegen Timing-Angriffe auf MAC-Vergleiche besteht darin, AEAD-Modi (GCM, ChaCha20-Poly1305) zu verwenden und die MAC-Prüfung an die kryptografische Bibliothek zu delegieren. Bibliotheksimplementierungen führen die Prüfung intern in konstanter Zeit aus. Wenn Sie AEAD korrekt verwenden (die Entschlüsselung schlägt bei jeder Manipulation fehl und wird niemals vor der Verifizierung des Tags durchgeführt), müssen Sie MAC-Tags nie im Anwendungscode vergleichen. Dadurch wird die Timing-Sicherheitslücke vollständig beseitigt.
Auf Timing-Sicherheitslücken testen
Das Testen auf Timing-Sicherheitslücken erfordert eine statistische Analyse der Verteilungen von Antwortzeiten. Tools wie tlsfuzzer, Skripte zum Testen von Timing-Angriffen und das dudect-Framework helfen dabei, Zeitunterschiede in kryptografischen Implementierungen zu erkennen. Ein t-Test der Antwortzeitstichproben für Eingaben, die zu gleichen Laufzeiten führen sollten, kann statistisch signifikante Unterschiede aufdecken. Falsch-negative Ergebnisse sind möglich; zusätzlich zu Tests ist daher auch eine Überprüfung des Codes auf konstante Laufzeit unerlässlich.
Vergleich in konstanter Zeit
Welche Python-Funktion sollte verwendet werden, um einen HMAC-Tag sicher und ohne Gefahr von Timing-Angriffen zu vergleichen?
Zusammenfassung der Timing-Angriffe
Zusammenfassung der Timing-Angriffe: Vergleiche von Zeichenfolgen mit vorzeitigem Abbruch geben geheime Werte Byte für Byte über Unterschiede in den Antwortzeiten preis; über ein Netzwerk sind diese Unterschiede mit genügend Stichproben messbar; verwenden Sie hmac.compare_digest in Python und CRYPTO_memcmp in OpenSSL für Vergleiche in konstanter Zeit; Timing-Angriffe auf RSA-Padding können private Schlüssel kompromittieren (verwenden Sie RSA mit konstanter Laufzeit und OAEP); Timing-Angriffe auf AES-Tabellenzugriffe geben Schlüsselbits preis (verwenden Sie AES-NI oder Bit-Slicing-Implementierungen); und die Verifizierung durch AEAD-Bibliotheken macht MAC-Vergleiche auf Anwendungsebene überflüssig.
Häufig gestellte Fragen
Ist die Lektion „Timing-Angriffe in Code auf Anwendungsebene“ kostenlos?
Ja — der vollständige Text von „Timing-Angriffe in Code auf Anwendungsebene“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Cryptology Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Cryptology Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Timing-Angriffe in Code auf Anwendungsebene“?
Lernen Sie, wie das Timing von String-Vergleichen Geheimnisse preisgibt und wie zeitkonstante Vergleiche dies verhindern. Du übst Cryptology Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Cryptology Academy zu starten?
Keine Vorkenntnisse erforderlich. Cryptology Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Timing-Angriffe in Code auf Anwendungsebene“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Cryptology Academy-Lektion Code schreiben und ausführen?
Ja. Jede Cryptology Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Padding-Oracle-Angriffe im Detail
- Replay-Angriffe und Schwachstellen durch Nonce-Wiederverwendung
- Timing-Angriffe in Code auf Anwendungsebene
- Die häufigsten Muster für den Fehlgebrauch von Kryptografie