· 

Passwörter würzen

1. Einführung

Um gegenüber einem Online-Dienst nachzuweisen, dass man tatsächlich derjenige ist, für den man sich ausgibt, verwendet man oft wissensbasierte Authentifizierungsverfahren wie das klassische Passwort. Hierbei muss eine Information erinnert werden, die man bei der Registrierung angegeben hat. Von dem eigenen Namen, über Geburtsdaten bis hin zu kryptischen Aneinanderreihung von Zeichen, ist in der breiten Öffentlichkeit alles vertreten. Je vorhersagbarer ein Passwort ist, desto schlechter ist der dadurch erreichte Schutz. Es gibt aber noch ein weiteres Problem, das mit Passwörtern einhergeht: Woher wissen die Online-Dienste wie z. B. Facebook, Amazon, Google oder Netflix, wie das von dir gewählte Passwort lautet? Nun, sie speichern es in einer Datenbank und wenn du dein Passwort angibst, wird in der Datenbank nachgeschaut, ob deine Angabe mit der Angabe übereinstimmt, die unter deinem Benutzernamen hinterlegt ist. Aber mal angenommen jemand stiehlt die Datenbank, in der alle Benutzernamen, E-Mail-Adressen und dazugehörige Passwörter gespeichert sind. Was würde das für die Benutzer bedeuten?


2. Passwort-Hashes

Zunächst einmal würde nicht viel passieren, da jeder Anbieter (zumindest vorgibt) die Passwörter der Benutzer nicht im Klartext zu speichern. Wer Passwörter jedoch (unverschlüsselt) im Klartext speichert, handelt nicht nur grob fahrlässig, sondern macht sich auch strafbar! Außer natürlich, es kommt ein Gesetz, mit dem die Herausgabe von Klartextpasswörtern in bestimmten Fällen legitimiert wird, doch in dieser Hinsicht ist man zum Glück zurückgerudert.

Wie stellt man nun sicher, dass der Online-Dienst dein Klartextpasswort nicht kennt aber dennoch durch die Eingabe deines Passwort verifizieren kann, dass dieses Passwort das richtige ist? Ganz einfach: Über Hash-Funktionen.

Eine Hash-Funktion ist eine mathematische Einwegfunktion, d. h. die Berechnung des Funktionswerts f(x) ist sehr leicht möglich, doch die Umkehrung (also für ein bestimmtes f(x) das dazugehörige x zu finden) ist nur theoretisch und praktisch quasi nicht möglich. Als Basis verwendet man mathematische Problemstellungen, die sehr schwer zu lösen sind, wie etwa das diskrete Logarithmus-Problem oder ein hinreichend schneller Algorithmus zur Faktorisierung von Primzahlen. Ein bekannter Hash-Algorithmus ist bspw. SHA512. Wenn man das Klartextpasswort

Passwort

als Input in diese Hash-Funktion gibt, dann erhält man als Ergebnis

aaf6a7d781d14ad069bf26988cbda52043197c14f3a9762778a7ba9d31bebce0bfbb27368e39c18471dc611731877cd4796b80c660ff9be2d0d63eaa649c4c1d

In der Praxis verwendet man Hash-Funktionen, die möglichst lange für die Berechnung eines solchen Hash-Werts brauchen. Wenn ein Angreifer nämlich mit einer Brute Force Attacke einfach versucht, alle Möglichkeiten durchzugehen, dann sollte er nicht Millionen von Operationen pro Sekunde ausprobieren können, sondern so lange wie möglich damit beschäftigt sein, diese Werte zu berechnen.

Wenn du dich also mit deinem Benutzernamen und deinem Passwort auf einer Webseite anmeldest, dann wird mit deinem Benutzernamen in einer Datenbanktabelle nach dem zu deinem Passwort gehörenden Hash gesucht und das Ergebnis mit dem Hash des Passworts verglichen, das du soeben eingegeben hast.

So viel weißt du bereits aus meinem Video Wie Hacker Passwörter knacken. Die eigentliche Frage dieses Artikel ist allerdings, was man mit dem Würzen von Passwörtern meint. Nun, zum Würzen verwendet man u. a. Salz und Pfeffer. Und genau diese beiden Gewürz-Sorten findet man auch im IT-Sicherheitsumfeld.


3. Passwörter salzen (Salt)

Wenn man ein Passwort salzt, dann meint man damit, dass vor dem Hashen des Klartextpassworts ein zufälliger String an das Passwort angehängt wird und das so gebildete Wort gehasht wird. Statt also den Hash des unsicheren Passworts 

Passwort

zu speichern, hängt man eine zufällige Zeichenkette, z. B.

@12$_!

an das Passwort an und hasht somit 

Passwort@12$_!

Das ergibt beim SHA512-Algorithmus dann wiederum

1e945d74a9499f6315fa5535576f9cfd5e43bfcc1f01c9dfb408bfa02eb9d88cf375114b5544d155436adc8499300fb5a28887ee54a07f349ed24fd985921a5c

Da man als Benutzer sich sein Salt nicht merken möchte und/oder merken kann, wird es separat gespeichert, damit man nach wie vor nur das Passwort eingeben muss. Warum veranstaltet man diesen Zirkus überhaupt? Ist der Hash-Wert nicht sicher genug? Nein! Da Anwender oft sehr einfache Passwörter verwenden, kann man im Vorfeld mit Passwortlisten Tabellen generieren, die Passwörter samt den dazugehörigen Hashes führen.

Es gibt im Wesentlichen drei große Vorteile, die das Salzen von Passwörtern mit sich bringt:

  1. Das Passwort des Benutzers wird schwieriger zu knacken, da es durch das angehängte Salt komplexer wird.
  2. Da das Salt zufällig für jeden Benutzer generiert wird, muss man für jeden Benutzer von einem anderen Salt ausgehen und dadurch dauern Angriffe auf mehrere Benutzer sehr lange. 
  3. Der Aufwand, um im Vorfeld Tabellen mit häufig verwendeten Passwörtern samt ihren Hashes zu erstellen, ist enorm hoch, da man für jeden Benutzer eine solche Tabelle erstellen muss (selbst wenn das Salt bekannt ist). Das Salt ist oft aber nicht bekannt und demnach muss man zusätzlich zu den potentiellen Passwörtern Zeichenketten anhängen, die (im Optimalfall) völlig zufällig sind.

Das Salt an sich bietet zwar ein zusätzliches Maß an Sicherheit, doch diese reicht oft immer noch nicht aus. Warum? Wie ich bereits erwähnt habe, muss das Salt gespeichert werden, da der Benutzer es sich entweder nicht merken kann bzw. will und dieses möglichst zufällig sein sollte. Die Zufälligkeit dieses Salts muss gegeben sein, denn ansonsten bietet es genauso wenig Schutz wie bei SAP-Systemen. Dort wird nämlich als Salt einfach nur der Benutzername verwendet. Klar, das Salt ist für jeden Benutzer verschieden, allerdings ist der Algorithmus zur Bildung des Salts mehr als trivial, weil du nur den entsprechenden Benutzernamen an das Passwort anhängen musst.  

Android bietet da schon mehr Schutz: Hier wird nämlich eine Zufallszahl berechnet, diese mit dem SHA1-Algorithmus gehasht und dieser Hash als Salt an das Klartextpasswort gehängt. Dadurch, dass der Hash allerdings gespeichert ist, kannst du ihn auch einsehen. Wenn das Target-Smartphone gerootet ist und USB-Debugging eingeschaltet wurde, dann kann man mit der Android Debug Bridge (adb) und dem Befehl pull die locksettings-Datenbank unter /data/system/locksettings.db extrahieren. Diese enthält in der Tabelle locksettings ein Feld lockscreen.password_salt, das das Smartphone spezifische Salt im Klartext enthält. Damit ist der Prozess des Passwortknackens wieder in einem realistischen Maße erfolgreich.


4. Passwörter pfeffern (Pepper)

Um dieses Problem mit dem in der Datenbank gespeicherten Salt zu beheben, gibt es einen weiteren Würz-Mechanismus, nämlich das sogenannte Pfeffern. Beim Pfeffer wird ebenfalls eine zufällige Zeichenkette an das Passwort angehängt. Der Unterschied zum Salt ist jedoch, dass das Pepper nicht für jeden Benutzer verschieden ist, sondern quasi für alle Benutzer in der Datenbank gilt. Es handelt sich also um einen statischen Wert. Dieser wird allerdings nicht in der Datenbank gespeichert. Das NIST (National Institute of Standards and Technology) empfiehlt, dass das Pepper separat (also nicht in derselben Datenbank wie die Hashes) gespeichert wird (z. B. in einer Konfigurationsdatei oder hart-kodiert im System). 

In modernen Systemen werden beide Mechanismen (also Salzen und Pfeffern) verwendet, um dem Benutzer ein herovorragend gewürztes Passwort zu kredenzen. Man muss sich auch nicht an die Reihenfolge der Konkatenierung (also das Zusammenfügen des Salts und des Peppers an das Passwort) halten, sondern kann z. B. das Pepper vorne und das Salt hinten an das Passwort anhängen. Ich habe im Arbeitskontext für eine kritische Web-Anwendung auch einen eigenen Algorithmus zur Benutzerauthentifizierung entworfen, der ebenfalls nicht einfach nur das Salt und Pepper an das eigentliche Passwort anhängt. Die Mischung macht es eben ...