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.941 Themen, 20.708 Beiträge
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.
Ich vermute mal Du meinst hier 10^25. 1^25 wäre zumindest nicht sehr gut...
Danke, ich hab bei den Potenzen insgesamt geschludert. Es war einmal 2 * 10^19 und einmal 1 * 10^25 gemeint.
Ja gut, das kann man nicht verhindern denn:
Es geht darum Passwörter nicht im Klartext in die Nutzertabelle zu schreiben.
Richtig ist das Passwort einmal zu hashen - kryptographish sicher also MD5 oder SHA2-Familie,
hingegen sind MD4 und SHA1 so gut wie geknackt und CRC32 ist als kryptographisch sichere Funktion garnicht gedacht.
Nun geben Benutzer gern leichte Passwörter wie "123" ein. Vom Hash lässt sich der Inhalt zwar nicht zurückberechnen, aber es gibt Gigabytegroße Übersetzungstabellen die solche einfachen Spielereien im Standartrepertoire haben.
Klaut dir nun jemand deine Nutzertabelle vom SQL Server sind viele Nutzer offen.
Dagegen wirkt ein Salt. Davon braucht man auch nur eins. Ein globales für alle Nutzer "5gHH/u8$]a.Zas" ist aber auch nicht das gelbe vom Ei.
Als sicher gilt das Konzept jedem User ein neues (gutes) Salt zu generieren, dieses mit dem Klartext-Password zu hashen und dann Hash und Salt in die Nutzertabelle zu speichern.
Ein Angreifer hat nun statt 100 Nutzern mit 1 Salt für die er 1 Übersetzungstabelle berechnen muss, 100 Salts für die er 100 Übersetzungstabellen berechnen muss, und eine gute Tabelle dauert schon verdammt lang.
Als Salt kann man zum Beispiel die aktuelle Systemzeit mit microsekunden hashen.
Ich werfe mal ein Thema auf, was nie einer mag: Aufwand... Nutzen?
Poste mal, worum es geht, dann sollte man abwägen ob so einer Sicherung wirklich effektiv ist... ich z.B. finde die Methode super:
SSL verschlüsselter Kanal, Passwörter werden in MD5 und zusätzlich in SHA gespeichert... so verhindert man, dass Worte, die den gleichen MD5 Hash haben aber nicht das PW sind, anerkannt werden. Hinzu einen Timeout für auto-log-off sowie eine Art Log, wer wann sich eingeloggt hat und wann ein PW geändert wurde. Da gibt es viele Möglichkeiten!
Es gibt aber auch einige Grundsätze sie man bei so ner Entwicklung beachten sollte:
Aufwand und Nutzen, ERinsatzgebiet, Relevanz... außerdem sollte man NIE mehr Daten also nötig online verfügbar machen - ob Verschlüsselt oder nicht =)
Das beste ist wirklich über mehrere Hash-Verfahren paralell zu arbeiten, sodass du immer den einen String brauchst, der für alle gewählten Verfahren stimmt. Aber du machst dir ja eher nen Plan über die Speicherung als über das Knacken - wo speicherst du denn deine Daten? =)
Bei kleinen einfachen Projekte nurtze ich auch "nur" MD5... solange keine Sau an die Haswerte rankommt, bleibt nur durchtesten! Und wenn Leute an deine Tabellen kommen KÖNNTEN, dann liegt das Problem nicht in der PW Speicherung sondern eher in anderen Zugriffspfaden.