PHP: wie soll man richtig das Passwort speichern (SHA1, MD5 usw.)

23 Nov 2008 um 12:44 - PHP

Wenn Sie komplexe Internetseiten betreiben, dann müssen Sie die Tabelle mit den Benutzernamen und Passwörter speichern. Da man sich immmer versichern will, werden die Passwörter kodiert gespeichert. Warum und wie eigentlich richtig kodieren?

Die Notwendigkeit der Kodierung besteht darin, dass der Hacker den Zugriff zur Tabelle mit Benutzerdaten bekommen kann. Falls dies vorkommen würde, dann könnte sich der Hacker mit den kodierten Passwörtern nicht einloggen. Deshalb wird die Einwegfunktion verwendet, die zu einer Zeichenfolge (Passwort) eine Abbildung (kodiertes Passwort) erzeugt. Diese Abbildung soll nicht umkehrbar sein, damit der Hacker aus dem kodierten Passwort kein richtiges bekommen kann.

Der Benutzer meldet sich durch das Formular mit dem nicht-kodierten Benutzer und Passwort (Clientseite). Auf der Serverseite werden sie kodiert und mit den kodierten Daten aus Datenbank verglichen. Wenn die gleich sind, dann wird der Benutzer erfolgreich identifiziert und die Anmeldung ist möglich.

Häufig wird MDA5- oder SHA1-Funktion als Einwegfunktion verwendet. Diese werden bereits als PHP Funktion programmiert.

MD5 erzeugt aus einer Zeichenfolge (Text, Passwort, Benutzername) eine 128-Bit-Abbildung (Hash oder Hashwert). MD5 Funktion in PHP gibt den Hash als 32 Zeichen lange Hexadezimalzahl (also Zeichenfolge aus "0..9a..f") zurück.

Es könnte sein, dass zwei unterschiedliche Schlüssel zum selben Hash-Wert führen. Dieses Ereignis wird als Kollision bezeichnet. Die Kollision ist unvermeidlich, da MD5 einer größeren Zeichenfolge (mehr als 128 Bit) eine 128-Bit-Wert abbildet. Um Wahrscheinlichkeit der Kollision zu minimieren, werden andere Funktionen verwendet, die den Hashwert größer als 128-Bit erzeugt. Eine davon ist SHA1 mit 160-Bit-Abbildung - schon besser, aber Kollision ist sowieso möglich.

SHA1-Funktion in PHP gibt als Rückgabewert ein 40 Zeichen langer Hexadezimalwert zurück.

Zwar haben Sie die Passwörter kodiert gespeichert, aber für Hacker ist es kein Problem :)

Der Hacker kann den Zugriff zur Datenbank durch SQL-Injection oder auf andere Weise bekommen. Die kodierten Daten werden dann entschlüsselt. In diesem Fall können wir nicht über klassische Entschlüsselung sprechen, sondern die passende Antwort wird gefunden:

Das gewöhnliche Passwort besteht meistens aus 6-12 Buchstaben mit 1-4 Ziffern. Häufig wird ein Wort und eine Zahl zusammen verwendet (z.B. "anton1984" oder "monika_berger_27" usw.)
Um alle Variante zu finden, brauchen wir ein Wörterbuch mit den am häufigsten benutzten Wörtern. So sieht das "klassische" dumme Verfahren für Entschlüsselung aller Passwörter mit 4 Symbolen aus Buchstaben und Ziffern:

$abc="abcdefghijklmnopqrstuvwxyz0123456789";
for($i1=0;$i1<36;$i1++)
   for($i2=0;$i2<36;$i2++)
       for($i3=0;$i3<36;$i3++)
           for($i4=0;$i4<36;$i4++) {
$vorschlag=$abc[$i1].$abc[$i2].$abc[$i3].$abc[$i4];
if (sha1($vorschlag)==$gespeichertes_passwort)
echo "Passwort ist $vorschlag";
}

Genauso für mehr als 4 Buchstaben, dazu können noch spezielle Symbole kommen ("_,-." und andere).

Um so eine direkte Entschlüsselung zu verhindern, muss man kein richtiges Passwort kodieren, sondern Passwort mit irgendwelchem Dientswort.

Nehmen wir an, das Passwort ist "anton84" - die Länge ist 7.
 - wenn man das direkt entschlüsselt, dann hängt die Schwierigkeit nur von der Länge ab (jehr größer Länge, desto schwieriger);
 - wenn man das mit dem Wörterbuch entschlüsselt, dann wird das Paar "anton" und "84" relativ schnell gefunden.

Wenn wir jetzt jedes Passwort noch mit dem Dienstwort "2xyz3" ergänzen, dann nimmt die Länge von 7 auf 12 zu (viel schwieriger/länger). Mit dem Wörterbuch-Verfahren ist es kaum zu entschlüsseln. Das Dienstwort "2xyz3" nennt man dann "Salz", mehr davon kann man hier erfahren.

Kommentare

Bisland keine Kommentare - sei der erste!


© 2008 Anton Pavlushko - Webentwicklung, Internetmarketing und Suchmaschinenoptimierung (SEO)

0.0068991184234619 sec