Hallo Zusammen,
es geht um das Thema Sicherheit beim Userlogin auf Websites, Stichwort md5 und Salt.
Bei Benutzerlogins via PHP in Verbindung mit MySQL sind wir uns alle einig, dass die Kennwörter verschlüsselt werden müssen. Nun ist md5 ja nicht gerade effektiv (selbst ich habe im Selbstversuch, da ich mich ja gerade damit befasse, eine Routine programmieren können, die die Kennwörter "ausliest", bzw. Strings mit dem selben Hash-Wert generiert).
Bei meinen Recherchen bin ich dann auf "Salt" gestoßen, was ich logischerweise irgendwo nachvollziehen kann. Nur die praktische Umsetzung verstehe ich noch nicht. Daher bitte ich die erfahrenen Leute hier, mir ein paar Denkanstöße zu geben, um ein möglichst sicheres Login für Benutzer zur Verfügung zu stellen.
Mein Lösungsansatz, wenn ich das alles Richtig verstanden habe, sieht in etwa so aus:
1. In der PHP-selber existiert bereits ein Pre-String in Sinne von "5gHH/u8$]a.Zas", der dem Kennwort vorne angehangen wird. Frage dazu: sollte dieser String auch verschlüsselt werden?
2. Das Benutzerkennwort wird mit md5 und sha verschlüsselt
3. Dann würde ich eine Zufallszahl erstellen (1-100), die einer ID in einer anderen Datenbank entspricht in der dann weitere Strings beinhaltet sind, die dem ganzen "hinten" angehangen werden. Bei dem Punkt bin ich mir aber nicht sicher, ob ich das richtig verstanden habe. Sollte Der String dann beim Login oder bei der Registrierung erfolgen? Ich denke mal eher beim letzteren und die Zufallszahl/ID wird ebenfalls in der Login-Datenbank gespeichert?!
Inwieweit bin ich da auf dem richtigen Weg, bzw. bringt dieser Ansatz überhaupt etwas? Welche Möglichkeiten hätte ich denn noch das ganze etwas sicherer zu machen? Natürlich wird es immer 'irgendwie' Möglich sein da reinzukommen :-( [lol, musste gerade an mein altes Dreamweaver denken, dass 'ganz einfach' einen Login ermöglicht und die Kennwörter im Klartext abspeichert ^^]
Existieren irgendwo im Netz bereits vorgefertigte Module/Scripte mit einer vernünftigen Verschlüsselung? Oder wäre generell davon abzuraten sowas zu nutzen, weil die 'Vorgehensweise' ja bekannt ist?!
Informatives zum Thema wäre willkommen, vielleicht auch für andere User hier interessant, weil es ja doch ein heikles Thema ist und immernoch viel zu viele Leute 'nur' md5 verwenden....
Danke im Voraus für Eure Mühen,
Innu
Programmieren - alles kontrollieren 4.940 Themen, 20.676 Beiträge
1. In der PHP-selber existiert bereits ein Pre-String in Sinne von "5gHH/u8$]a.Zas", der dem Kennwort vorne angehangen wird. Frage dazu: sollte dieser String auch verschlüsselt werden?
Fangen wir mal gleich mit dem ersten Einwand an: Du schmeisst andauern Verschlüsselung und Hashfunktion durcheinander, deswegen ist mir nicht ganz klar, ob Dir der Unterschied bewusst ist.
Verschlüsselungen sind Zwei-Wege-Funktionen, ein Weg zum Ver-, einer zum Entschlüsseln. Demgegenüber sind Hashfunktionen Einbahnstraßen, im Idealfall gibt es keinen schnelleren Weg als Brute Force um aus einem Hash wieder auf den Klartext zu kommen.
Jetzt zu deiner Frage: Nein, Du musst einen Salt nicht "verschlüsseln" (was auch immer Du dabei jetzt meinst), er darf nur Außenstehenden nicht bekannt sein, denn dann wäre er sinnlos.
2. Das Benutzerkennwort wird mit md5 und sha verschlüsselt
Was meinst Du mit UND? Wendest Du beide Funktionen nacheinander darauf an? Falls ja: Entgegen landläufiger Meinung erhöht die "Reihenschaltung" mehrerer Hashfunktionen nicht die Sicherheit des Hashes, im Gegenteil. Das kann man auch ganz einfach einleuchtend erklären. Nehmen wir als erstes MD5:
Du erstellst aus einem beliebigen Klartext der Länge N einen Hash der aus 32 chars aus dem Pool [0-9, a-f] besteht. Die Entropie beträgt also 16 hoch 16 = 18446744073709551616 (rund 2 hoch 19). Hiervon abziehen musst Du noch eine unbekannte Anzahl von möglichen Kollisionen.
Dein vorheriger Klartext hatte eine Entropie von (Anzahl verfügbarer Zeichen) hoch (Länge des Strings). Nehmen wir einmal an Du lässt nur Zahlen, Groß- und Kleinbuchstaben zu, so hast Du einen Pool von [0-9, a-z, A-Z] = 62 Zeichen. Bei einer vorgegebenen Mindeslänge von 6 Zeichen und einem Salt von 8 Zeichen hattest Du schon eine Entropie von rund 1 hoch 25 (Eine Ausnahme bildet hier DES, da es nur die ersten 8 Zeichen des Klartextes nutzt).
Wenn Du also auf das Ergebnis einer Hashfunktion wieder eine Hashfunktion anwendest verringerst Du die Entropie und erhöhst die Wahrscheinlichkeit einer Kollision. Also eine schlechte Idee.
3. Dann würde ich eine Zufallszahl erstellen (1-100), die einer ID in einer anderen Datenbank entspricht in der dann weitere Strings beinhaltet sind, die dem ganzen "hinten" angehangen werden. Bei dem Punkt bin ich mir aber nicht sicher, ob ich das richtig verstanden habe. Sollte Der String dann beim Login oder bei der Registrierung erfolgen? Ich denke mal eher beim letzteren und die Zufallszahl/ID wird ebenfalls in der Login-Datenbank gespeichert?!
Der Satz: "Sollte Der String dann beim Login oder bei der Registrierung erfolgen?" macht irgendwie keinen Sinn, was sollte der Sting? Eingegeben werden? Ausgelesen werden? Genutzt werden?
Primär ist bei einem salted hash nur eines wichtig: Der Salt darf einem möglichen Angreifer nicht bekannt sein, und dazu zählt auch der Nutzer selbst. Andererseits solltest Du Dich davor hüten das Problem zu ver-komplizieren. Übertriebene Komplexität erhöht die Versagenswahrscheinlichkeit und die Fehlerquote. Ergo nutze eine bereits getestete fertige Funktion wie z.B. hash_hmac() mit einem von Dir selbst festgelegten Salt, dieser kann ruhig für alle Nutzerpasswörter identisch sein, so lange er geheim bleibt.
Fangen wir mal gleich mit dem ersten Einwand an: Du schmeisst andauern Verschlüsselung und Hashfunktion durcheinander, deswegen ist mir nicht ganz klar, ob Dir der Unterschied bewusst ist.
Verschlüsselungen sind Zwei-Wege-Funktionen, ein Weg zum Ver-, einer zum Entschlüsseln. Demgegenüber sind Hashfunktionen Einbahnstraßen, im Idealfall gibt es keinen schnelleren Weg als Brute Force um aus einem Hash wieder auf den Klartext zu kommen.
Jetzt zu deiner Frage: Nein, Du musst einen Salt nicht "verschlüsseln" (was auch immer Du dabei jetzt meinst), er darf nur Außenstehenden nicht bekannt sein, denn dann wäre er sinnlos.
2. Das Benutzerkennwort wird mit md5 und sha verschlüsselt
Was meinst Du mit UND? Wendest Du beide Funktionen nacheinander darauf an? Falls ja: Entgegen landläufiger Meinung erhöht die "Reihenschaltung" mehrerer Hashfunktionen nicht die Sicherheit des Hashes, im Gegenteil. Das kann man auch ganz einfach einleuchtend erklären. Nehmen wir als erstes MD5:
Du erstellst aus einem beliebigen Klartext der Länge N einen Hash der aus 32 chars aus dem Pool [0-9, a-f] besteht. Die Entropie beträgt also 16 hoch 16 = 18446744073709551616 (rund 2 hoch 19). Hiervon abziehen musst Du noch eine unbekannte Anzahl von möglichen Kollisionen.
Dein vorheriger Klartext hatte eine Entropie von (Anzahl verfügbarer Zeichen) hoch (Länge des Strings). Nehmen wir einmal an Du lässt nur Zahlen, Groß- und Kleinbuchstaben zu, so hast Du einen Pool von [0-9, a-z, A-Z] = 62 Zeichen. Bei einer vorgegebenen Mindeslänge von 6 Zeichen und einem Salt von 8 Zeichen hattest Du schon eine Entropie von rund 1 hoch 25 (Eine Ausnahme bildet hier DES, da es nur die ersten 8 Zeichen des Klartextes nutzt).
Wenn Du also auf das Ergebnis einer Hashfunktion wieder eine Hashfunktion anwendest verringerst Du die Entropie und erhöhst die Wahrscheinlichkeit einer Kollision. Also eine schlechte Idee.
3. Dann würde ich eine Zufallszahl erstellen (1-100), die einer ID in einer anderen Datenbank entspricht in der dann weitere Strings beinhaltet sind, die dem ganzen "hinten" angehangen werden. Bei dem Punkt bin ich mir aber nicht sicher, ob ich das richtig verstanden habe. Sollte Der String dann beim Login oder bei der Registrierung erfolgen? Ich denke mal eher beim letzteren und die Zufallszahl/ID wird ebenfalls in der Login-Datenbank gespeichert?!
Der Satz: "Sollte Der String dann beim Login oder bei der Registrierung erfolgen?" macht irgendwie keinen Sinn, was sollte der Sting? Eingegeben werden? Ausgelesen werden? Genutzt werden?
Primär ist bei einem salted hash nur eines wichtig: Der Salt darf einem möglichen Angreifer nicht bekannt sein, und dazu zählt auch der Nutzer selbst. Andererseits solltest Du Dich davor hüten das Problem zu ver-komplizieren. Übertriebene Komplexität erhöht die Versagenswahrscheinlichkeit und die Fehlerquote. Ergo nutze eine bereits getestete fertige Funktion wie z.B. hash_hmac() mit einem von Dir selbst festgelegten Salt, dieser kann ruhig für alle Nutzerpasswörter identisch sein, so lange er geheim bleibt.