Kryptographisches Hashing: Ein Überblick

Ich bin ein Sicherheitsingenieur hier bei FloQast. Unser Sicherheitsteam ist funktionsübergreifend tätig, um die Risiken für das Unternehmen zu verwalten. Heute möchte ich über Hashing sprechen, das in einer SaaS-Anwendung mehrere wichtige kryptografische Zwecke erfüllen kann.

Beim kryptografischen Hashing werden Daten mathematisch verarbeitet, um eine Ausgabe abzuleiten, die als Platzhalter für das Original verwendet werden kann. Bei einer bestimmten Eingabe wird im Allgemeinen ein Hash (oder Digest) dieser Eingabe erstellt:

  • Eine einseitige, viele-zu-eins-Zuordnung von Eingabe zu Ausgabe;
  • Basierend auf einer mathematischen Formel;
  • Schon bei geringfügigen Änderungen der Eingaben kommt es zu erheblichen Leistungsänderungen;
  • Ausgabe einer langen Zahl mit einer festen Länge;
  • In der Lage, die Eingabe eindeutig zu identifizieren, aber die Eingabe nicht zu offenbaren.

(Hinweis: Hashing-Funktionen sind nicht nur für die Kryptographie geeignet. Das oben Gesagte gilt nicht immer zu 100% für andere Anwendungsfälle).

Kryptographisches Hashing ist nicht Verschlüsselung, weil sie nicht umkehrbar sein soll. Sicher, technisch gesehen könnte man Daten in etwas verschlüsseln, das gleich aussieht, und den Schlüssel wegwerfen, aber es könnte immer noch entschlüsselt werden, wenn jemand eine Kopie des Schlüssels hat. Hashing hingegen ist eher mit einem Fingerabdruck vergleichbar. Ein Fingerabdruck verrät uns nicht den Namen, das Alter, die Größe, das Gewicht oder die Lieblingsfarbe der Person, mit der er verbunden ist. Genauso wenig verrät ein Message Digest, wie lang die Eingabe war, ob es sich um ein Bild, einen Text oder etwas anderes handelte, ob das Wort FloQast in der Eingabe erscheint und so weiter.

Verschlüsseln wir die Nachricht HELLO, WORLD! im macOS-Terminal mit einem 256-Bit Secure Hash Algorithm (SHA-256) aufzurufen:

% echo -n 'HELLO, WORLD!' | shasum -a 256
b8d28d44584a6440028c72b4c7e774b11331e8f6f3cbae8ed482aef9c27fef74  -
% echo -n 'HELLO, WORLD!' | shasum -a 256
b8d28d44584a6440028c72b4c7e774b11331e8f6f3cbae8ed482aef9c27fef74  -
% echo -n 'HELLO, WORLD!' | shasum -a 256
b8d28d44584a6440028c72b4c7e774b11331e8f6f3cbae8ed482aef9c27fef74  -

Egal, wie oft wir einen SHA-256-Digest der Nachricht erstellen, die Ausgabe bleibt dieselbe - sie ist deterministisch. Dies gilt für mehrere Computer und Prozessorarchitekturen. Da die Ausgabelänge fest ist (immer 256 Bit) und kürzer als die maximal mögliche Eingabelänge, führt dieser Determinismus manchmal dazu, dass verschiedene Eingaben die gleiche Ausgabe erzeugen. Dies wird als Kollision bezeichnet.

Kollisionen können zu allen Arten von Sicherheitschaos führen, von Nachahmungen und Fälschungen bis hin zu zerstörten Quellkontrollsystemen. Ein guter crpytographischer Hash-Algorithmus minimiert nicht nur die Wahrscheinlichkeit von Kollisionen, sondern macht sie auch schwer vorhersehbar. Wenn wir unser obiges Beispiel dahingehend ändern, dass einer der Buchstaben klein geschrieben wird, können wir sehen, dass sich die Ausgabe völlig verändert hat:

% echo -n 'HeLLO, WORLD!' | shasum -a 256
6ef325dd396b1ce20cf8cc3815c9ceba0a9daaeb835d24f967d363ff65b0a78c  -

Obwohl eine Kollision für eine dieser Ausgaben und diesen speziellen Digest-Algorithmus bestehen kann, ist es unwahrscheinlich, dass wir sie durch einfaches Ersetzen von Buchstaben finden.

Da wir nicht effektiv von der Ausgabe zur Eingabe zurückgehen können, können wir eine Kopie der Ausgabe speichern und sie später verwenden. Wenn wir dies für eine Datei statt für eine Zeichenkette tun, können wir prüfen, ob sich der Inhalt überhaupt geändert hat:

% echo helloworld > message.txt
% shasum -a 256 message.txt
8cd07f3a5ff98f2a78cfc366c13fb123eb8d29c1ca37c79df190425d5b9e424d  message.txt
% echo Helloworld > message.txt
% shasum -a 256 message.txt
733b8d6bf076298654e1aa28d26a47f43f1cc0958476e19fc09444da2e7884de  message.txt

Wir können diese Methode nutzen, um festzustellen, ob sich der Inhalt einer Datei geändert hat, z. B. eine Kopie eines Vertrags oder ein wichtiges Stück Quellcode. Da die SHA-Chiffren (und einige andere) auf Schnelligkeit ausgelegt sind, eignen sie sich ideal für die Überprüfung der Integrität von Dateien, um festzustellen, ob sie manipuliert oder möglicherweise versehentlich beschädigt wurden, beispielsweise über eine unzuverlässige Netzwerkverbindung.

Sie könnten sogar auf die Idee kommen, SHA-256 für das Hashing von Kennwörtern in einer Datenbank zu verwenden. Das Problem dabei ist, dass es, weil es so schnell ist, nicht viel dazu beiträgt, einen Angreifer daran zu hindern, an Klartextpasswörter zu gelangen. Jeder, der eine Kopie der Datenbank hat, könnte die Hash-Werte vorberechnen und so jede Zeile mit einem Passwort von hello123 in wenigen Mikrosekunden.

Um dem entgegenzuwirken, kann die Verwendung eines langsameren Algorithmus oder einer Funktion zur Ableitung von Schlüsseln, die für das Hashing von Passwörtern entwickelt wurde, dazu beitragen, diese Art von Angriffen zu vereiteln, ohne dass legitime Benutzer dadurch belästigt werden. In ihrer einfachsten Form führen diese Prozesse einfach dazu, dass das Hashing um Größenordnungen länger dauert. Dadurch wird die Vorberechnung zeitlich sehr viel teurer.

Was wäre, wenn wir es auch möglich machen könnten, dass mehrere Zeilen das gleiche Passwort haben, ohne dass ihre Hashes gleich sind? Das ist Salting.

Ein Salt ist ein Stück zufällig generierter Daten, das als Teil des kryptografischen Hashing-Prozesses vorangestellt oder angehängt und dann zusammen mit dem Passwort gespeichert wird. Es ist nicht geheim, ganz und gar nicht, und sein Hauptzweck besteht darin, die Vorberechnung von Hashes unmöglich zu machen. In Kombination mit einer langsameren Hash-Funktion muss ein Hacker, der eine ganze Datenbank mit Passwörtern knacken will, Zeile für Zeile vorgehen, und das möglicherweise sehr langsam. Nehmen wir an, dass Ihr Salt zwei Bytes lang ist:

% echo -n '2sHELLO, WORLD!' | shasum -a 256
da1c8986242f128d2dea484483446b90dfa3a35b613121ca1de76eff68380907  -

% echo -n 'xfHELLO, WORLD!' | shasum -a 256
563f022aee539a070ebec1b1afd4c4e6aaab141ecff2c1886c4982cd084f9bc8  -

Wir stellen die beiden Bytes unserer ursprünglichen Zeichenkette voran HELLO, WORLD! und den Vorteil nutzen, dass sich die Eingabe drastisch ändert. Der einzige Haken an der Sache ist, dass wir beim Speichern des Hashes auch das Salt speichern müssen!

Wir schreiben jetzt das Jahr 2020. Vielleicht gibt es eine noch bessere Option: Single Sign-On, oder SSO. Dies ermöglicht es einem Dienst, überhaupt keine Passwortdaten zu speichern und sich stattdessen auf eine externe Behörde wie Google, GitHub oder einen Verzeichnisdienst zu verlassen, um die Passwortsicherheit zu gewährleisten. Wenn Sie dann versuchen, sich bei dem Dienst anzumelden, können Sie die Option wählen, sich mit einem externen Konto anzumelden. Bei vielen GitHub-Integrationen haben Sie beispielsweise die Möglichkeit, sich mit GitHub anzumelden: Wenn Sie versuchen, sich anzumelden, werden Sie auf die Anmeldeseite von GitHub weitergeleitet. Sobald die Anmeldung abgeschlossen ist, kehren Sie zur Integrationsseite zurück. Sie erhalten niemals eine Kopie Ihres Passworts.

Obwohl wir unseren Kunden sowohl eine passwortbasierte als auch eine SSO-Authentifizierung anbieten, empfiehlt FloQast jedem, das Verzeichnissystem der eigenen Organisation zu nutzen. Dies beschleunigt das Onboarding, fördert die Selbstbedienung und reduziert die Anzahl der Passwörter, die die Mitarbeiter erstellen müssen. Mehr Sicherheit für alle!

Andrew Merenbach

Andrew Merenbach ist der FloQast-Familie seit 2018 ein Dorn im Auge. Er ist ein Senior Security Engineer, dessen Name allein schon Bilder von Katzen, schlechten Witzen, Dinnerpartys und Rap-Songs mit Sicherheitsthemen hervorruft, manchmal alles auf einmal.



Zurück zu Blog