Sicherheit von MD5
Andreas
- programmiertechnik
0 Christoph Zurnieden0 Mulder0 Andreas
0 fastix0 Andreas
Hallo!
ich frage mich gerade wie sicher es ist, wenn ich eine Seite wie folgt schütze:
ca. 10 User bekommen eine email mit dem Link zu der gegen alle anderen Cracker... und böswilligen User zu schützenden Seite.
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
id bechränkt die zusammengehörigen User (ca. 10), und user_id ist ein MD5-String den ich wie folgt erzeuge(PHP):
srand ((double)microtime()*1000000);
$randvalue = rand();
$user_id = urlencode(md5($randvalue.$email_adresse));
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
32^36 / 10 = 1,5324955408658888583583470271503e+53
wobei mir hier immer verdächtig viele Zahlen drin sind, evtl läßt sich ein Algorythmus beschleunigen, aber auch das sollte nicht viel bringen, denn selbst 32^10 / 10 = 1.125.899.906.842.624
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Ich prüfe am Anfang des Sriptes in folgender Reihenfolge:
1. sind die $_GET[] Variablen überhaupt vorhanden?
2. Existiert die ID
3. Existiert zu dieser ID dieser User
sobald einer der Punkte nicht stimmt wird sofort abgebrochen!
Wir hatten ja schon einige Diskussionen zu dem Thema, hierbei wollte ich bewußt auf einen Login mit Passwort verzichten, denn ich sehe hier keinen gewinn an Sicherheit, wenn ich dem User an Stelle der kompletten URL einen Username und ein Passwort im Klartext schicken würde. Und das ist auch die einzige Schwachstelle an der ganzen Sache, die Klartext-Email, aber das Problem wird man wohl immer haben, aber wenn jemand der ein Interesse hat da einzubrechen bereits in der Lage ist entweder bei mir oder bei dem betroffenen User emails mitzulesen ist eh fast alles verloren!
Was meint Ihr dazu?
Grüße
Andreas
Hallo,
ich frage mich gerade wie sicher es ist, wenn ich eine Seite wie folgt schütze:
ca. 10 User bekommen eine email mit dem Link zu der gegen alle anderen Cracker... und böswilligen User zu schützenden Seite.
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
[...]
Was meint Ihr dazu?
Der Link ist abfangbar und der Inhalt des Links ist abfangbar.
Eine Sicherheit der Daten ist somit nicht gegeben.
Was Du brauchst ist SSL.
so short
Christoph Zurnieden
Hi!
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
[...]
Was meint Ihr dazu?
Der Link ist abfangbar und der Inhalt des Links ist abfangbar.
Eine Sicherheit der Daten ist somit nicht gegeben.
Was Du brauchst ist SSL.
Ja, das vergaß ich zu erwähnen, ohne hat das ganze natürlich wenig Sinn ;-)
Grüße
Andreas
Hallo
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
Was Du brauchst ist SSL.
Ja, das vergaß ich zu erwähnen, ohne hat das ganze natürlich wenig Sinn ;-)
Denn schrief ouck "https://..."!
*grummel*
;-)
Dann mach ich mal hier ein C&P des Originalpostings:
ich frage mich gerade wie sicher es ist, wenn ich eine Seite wie folgt schütze:
ca. 10 User bekommen eine email mit dem Link zu der gegen alle anderen Cracker... und böswilligen User zu schützenden Seite.
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
id bechränkt die zusammengehörigen User (ca. 10), und user_id ist ein MD5-String den ich wie folgt erzeuge(PHP):
srand ((double)microtime()*1000000);
$randvalue = rand();
$user_id = urlencode(md5($randvalue.$email_adresse));
Das ist unnötig kompliziert. MD5 alleine reicht. Allerdings ist die ID zu einfach, wenn, dann sollte die auch per MD5 verborgen werden.
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
32^36 / 10 = 1,5324955408658888583583470271503e+53
Und wenn Du noch erklärst, wie Du auf diese Funktion kommst? ;-)
wobei mir hier immer verdächtig viele Zahlen drin sind, evtl läßt sich ein Algorythmus beschleunigen, aber auch das sollte nicht viel bringen, denn selbst 32^10 / 10 = 1.125.899.906.842.624
Das ist enstschieden zu wenig!
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Nein. Eine Verzögerung alleine ist nicht sinnvoll. Nur das Beschränken auf eine begrenzte Zahl an Fehlversuchen hilft.
Wir hatten ja schon einige Diskussionen zu dem Thema, hierbei wollte ich bewußt auf einen Login mit Passwort verzichten, denn ich sehe hier keinen gewinn an Sicherheit, wenn ich dem User an Stelle der kompletten URL einen Username und ein Passwort im Klartext schicken würde.
Und was ist jetzt unterschiedlich?
Und das ist auch die einzige Schwachstelle an der ganzen Sache, die Klartext-Email, aber das Problem wird man wohl immer haben, aber wenn jemand der ein Interesse hat da einzubrechen bereits in der Lage ist entweder bei mir oder bei dem betroffenen User emails mitzulesen ist eh fast alles verloren!
Nicht nur fast. Deswegen ist ja auch keine Unterschied zur User/Password Kombination.
Es wird hier also noch eine kryptographische Methode benötigt, die Übergabe des Paswortes zu verschlüsseln. Diese Methode ist Open PGP, ein standardisierter Algorithmus http://www.ietf.org/html.charters/openpgp-charter.html, die Software dazu ist frei erhältlich http://www.gnupg.org/de/gnupg.html.
so short
Christoph Zurnieden
Hi!
Denn schrief ouck "https://..."!
*grummel*
;-)
sorry, in der Testphase verzichte ich noch darauf, daher hatte ich nicht daran gedacht ;-)
Dann mach ich mal hier ein C&P des Originalpostings:
ich frage mich gerade wie sicher es ist, wenn ich eine Seite wie folgt schütze:
ca. 10 User bekommen eine email mit dem Link zu der gegen alle anderen Cracker... und böswilligen User zu schützenden Seite.
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
id bechränkt die zusammengehörigen User (ca. 10), und user_id ist ein MD5-String den ich wie folgt erzeuge(PHP):
srand ((double)microtime()*1000000);
$randvalue = rand();
$user_id = urlencode(md5($randvalue.$email_adresse));
Das ist unnötig kompliziert. MD5 alleine reicht. Allerdings ist die ID zu einfach, wenn, dann sollte die auch per MD5 verborgen werden.
Was ist jetzt kompliziert? Das urlencode? Ja, das habe ich mir schon gedacht, ursprüngluch ging ich davon aus das md5() auch ungültige Strings ausspuckt, aber anscheinend nicht. ODe2r meinst Du das mit rand()? Das muß allerdings so bleiben, da man sonst sehr leicht auf den MD5() String kommen kann!
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
32^36 / 10 = 1,5324955408658888583583470271503e+53
Und wenn Du noch erklärst, wie Du auf diese Funktion kommst? ;-)
Naja, 32 Zeichen hat der MD5 String, so wie ich das sehe kann jedes zeichen entweder ein klein geschreibener Buchstabe sein(6 mögliche Zeichen), oder eine Zahl(10 mögliche Zeichen), also insgesamt 36 mögliche Zeichen, das macht 32^36 Möglichkeiten, und da er aber 10 verschiedene gültige Strings gibt, braucht der böse Bub ja nur 1/10 der Vesuche, also 32^36 / 10, und wenn meine Kopfrechenkenntnisse noch die sind die sie mal waren sollten das in etwa 1,5324955408658888583583470271503e+53 verschiedene Möglichkeiten sein, also eine 1 mit 53 Nullen!
wobei mir hier immer verdächtig viele Zahlen drin sind, evtl läßt sich ein Algorythmus beschleunigen, aber auch das sollte nicht viel bringen, denn selbst 32^10 / 10 = 1.125.899.906.842.624
Das ist enstschieden zu wenig!
Ja? Wenn ich ein sleep(1) einbaue, dann braucht er egal wie schnell das ganze quer über das Internet funktioniert immerhin im Idealfall 1.125.899.906.842.624 Sekunden, macht über den Daumen noch ca. 35.702.051 Jahre. Oder habe ich mich jetzt grob verrechnet?
Selbst wennihc das weglasse, vermutlich schafft er ca. 100, max 200 Anfragen in der Sekunde, wenn ich davon ausgehe er schafft 1000 pro Sekunde, dann braucht er immer noch 35.702 Jahre!
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Nein. Eine Verzögerung alleine ist nicht sinnvoll. Nur das Beschränken auf eine begrenzte Zahl an Fehlversuchen hilft.
Wenn das den so einfach wäre, wie willst Du das machen? Das wurde schonmal groß und breit diskutiert, wenn der Angreifer sich auskennst kannst Du ihn im Prinzip schon beim 2. mal nicht mehr wiedererkennen!
Und das ist auch die einzige Schwachstelle an der ganzen Sache, die Klartext-Email, aber das Problem wird man wohl immer haben, aber wenn jemand der ein Interesse hat da einzubrechen bereits in der Lage ist entweder bei mir oder bei dem betroffenen User emails mitzulesen ist eh fast alles verloren!
Nicht nur fast. Deswegen ist ja auch keine Unterschied zur User/Password Kombination.
Es wird hier also noch eine kryptographische Methode benötigt, die Übergabe des Paswortes zu verschlüsseln. Diese Methode ist Open PGP, ein standardisierter Algorithmus http://www.ietf.org/html.charters/openpgp-charter.html, die Software dazu ist frei erhältlich http://www.gnupg.org/de/gnupg.html.
Das kann man wohl bei keinem GEschäftspartner als vorhanden voraussetzen, oder?
Grüße
Andreas
Hallo,
Denn schrief ouck "https://..."!
*grummel*
;-)
sorry, in der Testphase verzichte ich noch darauf, daher hatte ich nicht daran gedacht ;-)
Das sollte man nicht tun. Immer vollständig testen.
Dann mach ich mal hier ein C&P des Originalpostings:
[...]
id bechränkt die zusammengehörigen User (ca. 10), und user_id ist ein MD5-String den ich wie folgt erzeuge(PHP):
srand ((double)microtime()*1000000);
$randvalue = rand();
$user_id = urlencode(md5($randvalue.$email_adresse));
Das ist unnötig kompliziert. MD5 alleine reicht. Allerdings ist die ID zu einfach, wenn, dann sollte die auch per MD5 verborgen werden.
Was ist jetzt kompliziert? Das urlencode? Ja, das habe ich mir schon gedacht, ursprüngluch ging ich davon aus das md5() auch ungültige Strings ausspuckt, aber anscheinend nicht.
Genau, MD5 wirft eine Hexcodierte Zahl aus. [a-f0-9] (Können auch Großbuchstaben sein)
ODe2r meinst Du das mit rand()? Das muß allerdings so bleiben, da man sonst sehr leicht auf den MD5() String kommen kann!
Nein, warum?
Ein Passwort aus einem Generator (auch sowas ist standardisiert) reicht normalerweise. Kannst ja da noch MD5 drüberlegen.
rand() ist deshalb nicht gut, da es keine wirklicher Zufallsgenerator ist.
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
32^36 / 10 = 1,5324955408658888583583470271503e+53
Und wenn Du noch erklärst, wie Du auf diese Funktion kommst? ;-)
Naja, 32 Zeichen hat der MD5 String, so wie ich das sehe kann jedes zeichen entweder ein klein geschreibener Buchstabe sein(6 mögliche Zeichen), oder eine Zahl(10 mögliche Zeichen), also insgesamt 36 mögliche Zeichen,
Ich komme da auf 16 ;-)
das macht 32^36 Möglichkeiten, und da er aber 10 verschiedene gültige Strings gibt, braucht der böse Bub ja nur 1/10 der Vesuche, also 32^36 / 10, und wenn meine Kopfrechenkenntnisse noch die sind die sie mal waren sollten das in etwa 1,5324955408658888583583470271503e+53 verschiedene Möglichkeiten sein, also eine 1 mit 53 Nullen!
Das ist nicht ganz korrekt. Die MD5Sum ist wirklich eine Summe, also eine Zahl (128 Bit lang) keine Zeichenkette.
Gesamte Permutationsanzahl liegt also bei:
2^128 = 340.282.366.920.938.463.463.374.607.431.768.211.456
Die Statistik für die Wahrscheinlichkeit aus (2^128)-10 weißen Kugeln eine von 10 schwarzen zu ziehen überlasse ich Dir ;-)
wobei mir hier immer verdächtig viele Zahlen drin sind, evtl läßt sich ein Algorythmus beschleunigen, aber auch das sollte nicht viel bringen, denn selbst 32^10 / 10 = 1.125.899.906.842.624
Das ist enstschieden zu wenig!
Ja? Wenn ich ein sleep(1) einbaue, dann braucht er egal wie schnell das ganze quer über das Internet funktioniert immerhin im Idealfall 1.125.899.906.842.624 Sekunden, macht über den Daumen noch ca. 35.702.051 Jahre. Oder habe ich mich jetzt grob verrechnet?
Das ist für einen Zugang, aber ich kann soviele paralell laufen lassen, wie der Server hergibt solange Du keine Gegenmaßnahmen getroffen hast.
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Nein, siehe oben.
Ein schlichtes Login mit Zähler ist wirklich das einfachste und nach technischem Stand sicherste im Netz. (Vorrausgesetzt, die Übertragung selber ist verschlüsselt)
Nein. Eine Verzögerung alleine ist nicht sinnvoll. Nur das Beschränken auf eine begrenzte Zahl an Fehlversuchen hilft.
Wenn das den so einfach wäre, wie willst Du das machen? Das wurde schonmal groß und breit diskutiert, wenn der Angreifer sich auskennst kannst Du ihn im Prinzip schon beim 2. mal nicht mehr wiedererkennen!
Er muß erst Die ID (Den Usernamen) haben, darauf kannst Du dann den Zähler ansetzen. Wenn also eine ID versucht sich mehr als dreimal vergebens einzuloggen ist die ID gesperrt. Das ist eine sehr alte Technik, die sich sehr gut bewährt hat. Was spricht dagegen?
Es wird hier also noch eine kryptographische Methode benötigt, die Übergabe des Paswortes zu verschlüsseln. Diese Methode ist Open PGP, ein standardisierter Algorithmus http://www.ietf.org/html.charters/openpgp-charter.html, die Software dazu ist frei erhältlich http://www.gnupg.org/de/gnupg.html.
Das kann man wohl bei keinem GEschäftspartner als vorhanden voraussetzen, oder?
Das ist Vorraussetzung, ansonsten ist Snail Mail zu wählen.
Ja ich weiß, aber Sicherheit ist nicht zum Nulltarif zu haben, das kostet und wenn es "nur" Mühe ist.
so short
Christoph Zurnieden
Hi!
Das sollte man nicht tun. Immer vollständig testen.
Richtig, aber man muß ja nicht von Anfang an vollständig testen!
Genau, MD5 wirft eine Hexcodierte Zahl aus. [a-f0-9] (Können auch Großbuchstaben sein)
AHA! Wußte ich natürlich nicht, dadurch relativiert sich meine Rechnung ;-)
ODer meinst Du das mit rand()? Das muß allerdings so bleiben, da man sonst sehr leicht auf den MD5() String kommen kann!
Nein, warum?
Ein Passwort aus einem Generator (auch sowas ist standardisiert) reicht normalerweise. Kannst ja da noch MD5 drüberlegen.
rand() ist deshalb nicht gut, da es keine wirklicher Zufallsgenerator ist.
Was ist denn besser? Der von mir verwendete Code mit Microtime als srand() ist das zufälligste was PHP erzeugen kann, wenn ich den Kommentaren im Manual glauben schenken darf! Was soll ich denn statt dessen verwenden?
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
32^36 / 10 = 1,5324955408658888583583470271503e+53
Und wenn Du noch erklärst, wie Du auf diese Funktion kommst? ;-)
Naja, 32 Zeichen hat der MD5 String, so wie ich das sehe kann jedes zeichen entweder ein klein geschreibener Buchstabe sein(6 mögliche Zeichen), oder eine Zahl(10 mögliche Zeichen), also insgesamt 36 mögliche Zeichen,
Ich komme da auf 16 ;-)
das macht 32^36 Möglichkeiten, und da er aber 10 verschiedene gültige Strings gibt, braucht der böse Bub ja nur 1/10 der Vesuche, also 32^36 / 10, und wenn meine Kopfrechenkenntnisse noch die sind die sie mal waren sollten das in etwa 1,5324955408658888583583470271503e+53 verschiedene Möglichkeiten sein, also eine 1 mit 53 Nullen!
Das ist nicht ganz korrekt. Die MD5Sum ist wirklich eine Summe, also eine Zahl (128 Bit lang) keine Zeichenkette.
Gesamte Permutationsanzahl liegt also bei:
2^128 = 340.282.366.920.938.463.463.374.607.431.768.211.456
Die Statistik für die Wahrscheinlichkeit aus (2^128)-10 weißen Kugeln eine von 10 schwarzen zu ziehen überlasse ich Dir ;-)
Zumindest Sicher genug wieich finde, oder? Absolute Sicherheit gibt es nicht! Aber ich denke in der Tat inzwischen darüber nach, ob man zuusätzlich doch noch einen User-Login davorschalten soll...
wobei mir hier immer verdächtig viele Zahlen drin sind, evtl läßt sich ein Algorythmus beschleunigen, aber auch das sollte nicht viel bringen, denn selbst 32^10 / 10 = 1.125.899.906.842.624
Das ist enstschieden zu wenig!
Ja? Wenn ich ein sleep(1) einbaue, dann braucht er egal wie schnell das ganze quer über das Internet funktioniert immerhin im Idealfall 1.125.899.906.842.624 Sekunden, macht über den Daumen noch ca. 35.702.051 Jahre. Oder habe ich mich jetzt grob verrechnet?
Das ist für einen Zugang, aber ich kann soviele paralell laufen lassen, wie der Server hergibt solange Du keine Gegenmaßnahmen getroffen hast.
Ja, und das max. was ich bis jetzt an Parallelen "Angriffen" hinbekommen habe war unter 100 Requests pro Sekunde!
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Nein, siehe oben.
Ein schlichtes Login mit Zähler ist wirklich das einfachste und nach technischem Stand sicherste im Netz. (Vorrausgesetzt, die Übertragung selber ist verschlüsselt)
Aber das setzt doch voraus, das ich einen Weiteren Parameter brauche, die UserID, wenn möglich würde ich gerne einen weiteren Parameter verhindern, wie mache oich das am besten?
Nein. Eine Verzögerung alleine ist nicht sinnvoll. Nur das Beschränken auf eine begrenzte Zahl an Fehlversuchen hilft.
Wenn das den so einfach wäre, wie willst Du das machen? Das wurde schonmal groß und breit diskutiert, wenn der Angreifer sich auskennst kannst Du ihn im Prinzip schon beim 2. mal nicht mehr wiedererkennen!
Er muß erst Die ID (Den Usernamen) haben, darauf kannst Du dann den Zähler ansetzen. Wenn also eine ID versucht sich mehr als dreimal vergebens einzuloggen ist die ID gesperrt. Das ist eine sehr alte Technik, die sich sehr gut bewährt hat. Was spricht dagegen?
s.o.
Es wird hier also noch eine kryptographische Methode benötigt, die Übergabe des Paswortes zu verschlüsseln. Diese Methode ist Open PGP, ein standardisierter Algorithmus http://www.ietf.org/html.charters/openpgp-charter.html, die Software dazu ist frei erhältlich http://www.gnupg.org/de/gnupg.html.
Das kann man wohl bei keinem GEschäftspartner als vorhanden voraussetzen, oder?
Das ist Vorraussetzung, ansonsten ist Snail Mail zu wählen.
Ja ich weiß, aber Sicherheit ist nicht zum Nulltarif zu haben, das kostet und wenn es "nur" Mühe ist.
Naja, selbst dann hat man keine 100%ige Sicherheit, und wenn man hier mit solchen Maßstäben mißt muss man das überall tun. Wenn im Sicherheitskonzept das verschlüsseln von Mails nicht vorkommt kann man es vergessen. Außerdem schätze ich die Gefahr des abfangens von Emails nicht als wirklich groß ein - ja - sicher gibt es diese Gefahr, aber das ist doch nun mal wirklich nicht ganz so einfach als sich mit einem Brute-Force Tool einer Session zu bemächtigen.
Viele Grüße und Danke für die hilfreichen Antworten!
Andreas
Hallo,
Das sollte man nicht tun. Immer vollständig testen.
Richtig, aber man muß ja nicht von Anfang an vollständig testen!
Bei komplexen Programmen ist es möglich, das durch Hinzufügung weiterer Teile das das ehemals positiv Getestete im Zusammenhang nicht mehr funktioniert.
Wenn Du Teile testen willst, mußt Du das auch gleich von vornherein beachten. Einfach nur ein paar Zeilen schreiben und dann ausprobieren funktioniert nicht, damit kanst Du ganz schön auf die Schnauze fallen.
Genau, MD5 wirft eine Hexcodierte Zahl aus. [a-f0-9] (Können auch Großbuchstaben sein)
AHA! Wußte ich natürlich nicht, dadurch relativiert sich meine Rechnung ;-)
Nein, dadurch, das 16 < 36 ist ;-)
ODer meinst Du das mit rand()? Das muß allerdings so bleiben, da man sonst sehr leicht auf den MD5() String kommen kann!
Nein, warum?
Ein Passwort aus einem Generator (auch sowas ist standardisiert) reicht normalerweise. Kannst ja da noch MD5 drüberlegen.
rand() ist deshalb nicht gut, da es keine wirklicher Zufallsgenerator ist.
Was ist denn besser? Der von mir verwendete Code mit Microtime als srand() ist das zufälligste was PHP erzeugen kann, wenn ich den Kommentaren im Manual glauben schenken darf! Was soll ich denn statt dessen verwenden?
Ein ordentliches Login.
Gesamte Permutationsanzahl liegt also bei:
2^128 = 340.282.366.920.938.463.463.374.607.431.768.211.456
Die Statistik für die Wahrscheinlichkeit aus (2^128)-10 weißen Kugeln eine von 10 schwarzen zu ziehen überlasse ich Dir ;-)
Zumindest Sicher genug wieich finde, oder?
Ein ordentliches Login über SSL ist genauso sicher und vor allem problemloser. Das Letztere heißt natürlich auch, das die Fehlerwahrscheinlichkeit im Code sinkt. Somit ist ein derartiges Login sogar sicherer.
Absolute Sicherheit gibt es nicht!
Das kann ich nur unterschreiben.
Aber ich denke in der Tat inzwischen darüber nach, ob man zuusätzlich doch noch einen User-Login davorschalten soll...
Nein, wenn es über SSL geht reicht ein Userlogin. Alles andere ist nur komplizierter und damit fehleranfällig und somit unsicherer.
Das ist für einen Zugang, aber ich kann soviele paralell laufen lassen, wie der Server hergibt solange Du keine Gegenmaßnahmen getroffen hast.
Ja, und das max. was ich bis jetzt an Parallelen "Angriffen" hinbekommen habe war unter 100 Requests pro Sekunde!
Das ist aber sehr mager. Kleine Hardware?
Ein schlichtes Login mit Zähler ist wirklich das einfachste und nach technischem Stand sicherste im Netz. (Vorrausgesetzt, die Übertragung selber ist verschlüsselt)
Aber das setzt doch voraus, das ich einen Weiteren Parameter brauche, die UserID, wenn möglich würde ich gerne einen weiteren Parameter verhindern, wie mache oich das am besten?
Das verstehe ich nicht, was ist an den zwei Parametern (username/passwort) zuviel? Wenn Du die Loginversuche mitzählst hast Du noch einen Integer zum behalten, aber _das_ dürfte doch kein Problem darstellen, oder?
Versuche nicht das Rad neu zu erfinden, nimm das was schon da ist. Das ist bewährt und bekannt und läuft stabil.
Das ist Vorraussetzung, ansonsten ist Snail Mail zu wählen.
Ja ich weiß, aber Sicherheit ist nicht zum Nulltarif zu haben, das kostet und wenn es "nur" Mühe ist.
Naja, selbst dann hat man keine 100%ige Sicherheit,
Da bist Du aber juristisch auf der sicheren Seite.
Aber selbst da gilt, ich muß es erwähnen: "Auf hoher See und vor Gericht bist Du in Gottes Hand"
und wenn man hier mit solchen Maßstäben mißt muss man das überall tun.
Was spricht dagegen, es überall zu tun?
» Wenn im Sicherheitskonzept das verschlüsseln von Mails nicht vorkommt kann man es vergessen. Außerdem schätze ich die Gefahr des abfangens von Emails nicht als wirklich groß ein - ja - sicher gibt es diese Gefahr, aber das ist doch nun mal wirklich nicht ganz so einfach als sich mit einem Brute-Force Tool einer Session zu bemächtigen.
Es ist bedeutend einfacher, glaub's mir. Die ganzen Scriptkiddies sind lästig, aber nicht unbedingt gefährlich. Die gefährlichen Leute verfügen über besser Möglichkeiten und vor allem Sachverstand.
"Das ist aber _sehr_ unwahrscheinlich!" waren schon oft "letzte Worte"!
so short
Christoph Zurnieden
Hi Christoph!
Bei komplexen Programmen ist es möglich, das durch Hinzufügung weiterer Teile das das ehemals positiv Getestete im Zusammenhang nicht mehr funktioniert.
Das weiß ich auch aus eigener Erfahrung!
Wenn Du Teile testen willst, mußt Du das auch gleich von vornherein beachten. Einfach nur ein paar Zeilen schreiben und dann ausprobieren funktioniert nicht, damit kanst Du ganz schön auf die Schnauze fallen.
bin ich schon, und auch schon bei SSL, trotzdem implementiere ich das lieber nach und nach, auch da der SSL Server so nervig langsam ist...
Was ist denn besser? Der von mir verwendete Code mit Microtime als srand() ist das zufälligste was PHP erzeugen kann, wenn ich den Kommentaren im Manual glauben schenken darf! Was soll ich denn statt dessen verwenden?
Ein ordentliches Login.
Naja, wenn ich ne extra UserID im Link habe, habe ich ja denselben Effekt. Aber es soll wohl doch ein Extra Login vergeben werden, einmal, und dann brauche ich die ID ja gar nicht mehr, aber interessant ist das schon, denn wenn ich eine Variante ohne Login mache dann sollte die ID schon gut sein!
Ein ordentliches Login über SSL ist genauso sicher und vor allem problemloser. Das Letztere heißt natürlich auch, das die Fehlerwahrscheinlichkeit im Code sinkt. Somit ist ein derartiges Login sogar sicherer.
SSL kommt sowieso in den Link, ob Login oder nicht.
Ja, und das max. was ich bis jetzt an Parallelen "Angriffen" hinbekommen habe war unter 100 Requests pro Sekunde!
Das ist aber sehr mager. Kleine Hardware?
Hatten wir hier mal kürtzlich probiert, mit Philipp Hasenfratz, erst bei seinem Server, von ich glaub es waren 4 verschiedenen Maschinen aus, (auch von der eigenen), halt so viele Zugriffe auf ein einfaches PERL-Script wie möglich. Man konnt schön sehen das es eine Magische Grenze gab, die man sowohl mit 2 als auch mit 4 Rechnern nicht überschreiten konnte, daher würden 10.000 Rechner nichts bringen, udn ja, wie hatten auch fork... verwendet und die Scripte mehrmals gestartet... alles hat nichts gebracht! Ich glaube es waren gut 70 Requestst in der Spitze. Und er Server ist wirklich schnell gut angebunden gewesen, mein Rechner zu Hause über DSL hatte gerade mal 10 Requests geschafft! Und die Größenordnung hat andere auch nicht überrascht!
Das verstehe ich nicht, was ist an den zwei Parametern (username/passwort) zuviel? Wenn Du die Loginversuche mitzählst hast Du noch einen Integer zum behalten, aber _das_ dürfte doch kein Problem darstellen, oder?
Versuche nicht das Rad neu zu erfinden, nimm das was schon da ist. Das ist bewährt und bekannt und läuft stabil.
Jajaja, ich wollte nur kein login, brauch eich ja auch nicht mit der UserID, aber da ich es wahrscheinlich eh so machen soll, hat es sich erledigt, wobei die Kombination USerID und merkbares Passwort schon ein unterschied ist zu der 128-Bit ID => Login ist unsicherer!
Da bist Du aber juristisch auf der sicheren Seite.
Aber selbst da gilt, ich muß es erwähnen: "Auf hoher See und vor Gericht bist Du in Gottes Hand"
Denn Spruch kenn ich doch irgendwoher?
;-)
Aber das ist die kleinste Sorge die ich hier habe!
und wenn man hier mit solchen Maßstäben mißt muss man das überall tun.
Was spricht dagegen, es überall zu tun?
Würdest Du wenn Du so ein kleines Tool programmieren sollst das gesamte Sicherheitskonzept des Aufraggebers in Frage stellen? Klar, ein Hinweis ist wohl angebracht, aber damit ist es ja nicht getan! Das Probelm ist das die Geschäftspartene noch viel schwerer davon zu überzeugen sind, vor allem kann man das nicht mal eben implementieren, da bedarf es Know How wie das zu implementieren ist, und kostspielige Schulungen...
» Wenn im Sicherheitskonzept das verschlüsseln von Mails nicht vorkommt kann man es vergessen. Außerdem schätze ich die Gefahr des abfangens von Emails nicht als wirklich groß ein - ja - sicher gibt es diese Gefahr, aber das ist doch nun mal wirklich nicht ganz so einfach als sich mit einem Brute-Force Tool einer Session zu bemächtigen.
Es ist bedeutend einfacher, glaub's mir. Die ganzen Scriptkiddies sind lästig, aber nicht unbedingt gefährlich. Die gefährlichen Leute verfügen über besser Möglichkeiten und vor allem Sachverstand.
Ja, schätz mal bitte wieviele Leute dafür hier in Deutschland in Frage kommen - ein paar 1000 wenn Du mich fragst, und die werden meist andere Probleme haben als solche Mails abzufragen, die höchstens der Konkurrenz was bringen!
Grüße
Andreas
Christoph Zurnieden
Moin,
Das ist nicht ganz korrekt. Die MD5Sum ist wirklich eine Summe, also eine Zahl (128 Bit lang) keine Zeichenkette.
Jepp, aber wo du keine 128 Bit Entropie reinsteckst, kannst du auch keine 128 Bit Entropie rauskriegen. rand() spuckt einen integer aus, der in der Regel 32 Bit hat. Wenn also der andere Teil, über den die MD5-Summe berechnet wird, bekannt ist, brauchst du 'nur' noch 2^32 also 4294967296 Werte probieren.
Du möchtest also: a) mindestens 4 Zufallszahlen zusammenlegen (bitte nicht addieren, das würde eine Gaussche Verteilung geben und die ist Zufallsmäßig noch schlimmer), b) mt_rand() benutzen, c) falls deine Plattform es unterstützt /dev/random benutzen, d) dir evt. http://www.developers-resources.com/stories.php?story=01/12/03/3988084 ansehen.
Zu c): /dev/random blockiert, wenn es keine weitere Entropie mehr hat, bis es wieder welche zur Verfügung hat (die kommt von Usereingaben oder Festplattenaktivitäten, das kann also besonders auf einem Server ohne User davor länger dauern), du kannst also auch /dev/urandom benutzen, das schmeisst einen PRNG an, wenn ihm die Entropie ausgeht.
--
Henryk Plötz
Grüße von der Ostsee
Hallo,
Das ist nicht ganz korrekt. Die MD5Sum ist wirklich eine Summe, also eine Zahl (128 Bit lang) keine Zeichenkette.
Jepp, aber wo du keine 128 Bit Entropie reinsteckst, kannst du auch keine 128 Bit Entropie rauskriegen. rand() spuckt einen integer aus, der in der Regel 32 Bit hat. Wenn also der andere Teil, über den die MD5-Summe berechnet wird, bekannt ist, brauchst du 'nur' noch 2^32 also 4294967296 Werte probieren.
PHPs md5() funktioniert nicht, oder wie soll ich das verstehen?
Du möchtest also: a) mindestens 4 Zufallszahlen zusammenlegen (bitte nicht addieren, das würde eine Gaussche Verteilung geben und die ist Zufallsmäßig noch schlimmer),
Autsch.
Möchtest Du das da oben noch einmal korrigieren?
b) mt_rand() benutzen,
Da kenne ich den Code nicht, kann ich also nichts zu sagen.
c) falls deine Plattform es unterstützt /dev/random benutzen,
Sollte man nicht direkt benutzen. Aus Gründen, die Du selber unten aufführst.
d) dir evt. http://www.developers-resources.com/stories.php?story=01/12/03/3988084 ansehen.
Nett. Aber mit deren Erzeugung einer uniqid bin ich ganz und gar nicht einverstanden. Fehlt nicht auch die Erwähnung von RFC 1750?
Sehr schön ist übrigens die Möglichkeit, das thermische Rauschen der Soundkarte zu nutzen. Das bringt echte Zufallszahlen und auch eine ziemliche Menge/t. Ich selber habe mal etwas versucht mit ein paar OPAMPS und einem Wiederstand auf dem Paralellport. Hatte aber zu große CPU-Last verursacht, lohnte sich nicht (Kann auch mein Fehler gewesen sein ;-). Muß schon zumindest auf dem PCI Bus o.ä. sitzen.
Zu c): /dev/random blockiert, wenn es keine weitere Entropie mehr hat, bis es wieder welche zur Verfügung hat (die kommt von Usereingaben oder Festplattenaktivitäten, das kann also besonders auf einem Server ohne User davor länger dauern),
Na, das funktioniert zumindest unter Linux schon etwas geschickter mittlerweile ;-)
Siehe auch (in 2.2 zumindest an der Stelle, keinen 2.4er zur Hand gerade) den Kommentar in $KERNELSRC/drivers/char/random.c oben sowie im Code selber.
du kannst also auch /dev/urandom benutzen, das schmeisst einen PRNG an, wenn ihm die Entropie ausgeht.
Ja, reicht für die meisten Fälle.
so short
Christoph Zurnieden
Hallo,
Das ist nicht ganz korrekt. Die MD5Sum ist wirklich eine Summe, also eine Zahl (128 Bit lang) keine Zeichenkette.
Jepp, aber wo du keine 128 Bit Entropie reinsteckst, kannst du auch keine 128 Bit Entropie rauskriegen. rand() spuckt einen integer aus, der in der Regel 32 Bit hat. Wenn also der andere Teil, über den die MD5-Summe berechnet wird, bekannt ist, brauchst du 'nur' noch 2^32 also 4294967296 Werte probieren.
PHPs md5() funktioniert nicht, oder wie soll ich das verstehen?
doch, aber wenn aber 32 Bit Werte hat für die man die Prüfsumme bildet, hast Du auuch nicht mehr md5() strings zur Auswahl!
Du möchtest also: a) mindestens 4 Zufallszahlen zusammenlegen (bitte nicht addieren, das würde eine Gaussche Verteilung geben und die ist Zufallsmäßig noch schlimmer),
Autsch.
Möchtest Du das da oben noch einmal korrigieren?
Das kann ich auch nicht nachvollziehen?! Was sollte man statt dessen machen? Wie soll ich 4 verbinden?
Ich hätte da noch ein paar Werte die mir in Verbundung mit rand(), mt_rand(), srand() und md5() doch eine zimlich zufällige ID liefern müssten:
php PHPSESSID
Apache UNIQUE_ID
microtime //immerhin 1 Mio Zahlen pro Sekunde!
email-Adresse, Referer, IP
Wie könnte ich aus all diesen doch recht zufälligen und schwer erratbaren Daten eine gute ID machen, mit möglichst vielen bit?
Leider habe ich für die anderen geposteten Lösungen nicht genügend Rechte!
Grüße
Andreas
Moin,
Das kann ich auch nicht nachvollziehen?! Was sollte man statt dessen machen? Wie soll ich 4 verbinden?
Siehe Nachbarpost. Am besten wäre natürlich aus jeder Zahl 4 Binärzeichen zu machen und die dann alle als String aneinderzuhängen. Einfach statt + den . benutzen, um sie dann von PHP automatisch nach String konvertieren zu lassen und letztlich diese Strings zusammenzucatten. Sowas in der Art von md5(mt_rand().mt_rand().mt_rand().mt_rand().$sonstwas_zumbeispiel_email) sollte tun. (Seeden nicht vergessen, wenn dein PHP < 4.2 ist!)
--
Henryk Plötz
Grüße von der Ostsee
Hallo!
Siehe Nachbarpost. Am besten wäre natürlich aus jeder Zahl 4 Binärzeichen zu machen und die dann alle als String aneinderzuhängen. Einfach statt + den . benutzen, um sie dann von PHP automatisch nach String konvertieren zu lassen und letztlich diese Strings zusammenzucatten. Sowas in der Art von md5(mt_rand().mt_rand().mt_rand().mt_rand().$sonstwas_zumbeispiel_email) sollte tun. (Seeden nicht vergessen, wenn dein PHP < 4.2 ist!)
Warum muß man das nur bis 4.2?
mt_srand((double)microtime()*1000000);
$randval = mt_rand();
md5(mt_rand().
session_id().
mt_rand().
$_SERVER['UNIQUE_ID'].
mt_rand().
microtime().
mt_rand().
$email);
Was sagst Du dazu? Wenn das nicht unique ist ;-)
Grüße
Andreas
Hi!
mt_srand((double)microtime()*1000000);
$randval = mt_rand();
md5(mt_rand().
session_id().
mt_rand().
$_SERVER['UNIQUE_ID'].
mt_rand().
microtime().
mt_rand().
$email);
Was vielleicht noch zu beachten wäre, ich müßte teilweise 10-20 Zufallszahlen in einer Schleife generieren. Das ist egal, oder?
Grüße
Andreas
Moin,
PHPs md5() funktioniert nicht, oder wie soll ich das verstehen?
Nein, aber MD5 fügt selbst keinen Zufall hinzu. 2^32 mögliche Eingabewerte (bei zweiter Betrachtung: rand() spuckt sogar nur positive Zahlen aus, also ist das noch weniger) können nur 2^32 mögliche Ausgabewerte produzieren.
Möchtest Du das da oben noch einmal korrigieren?
Wieso sollte ich? Erinnerst du dich noch an Stochastik in der Schule? Du weisst schon, die Sache mit den Würfeln: Wenn du einen Würfel betrachtest, sind die Ergebnisse gleichverteilt - jede Zahl hat eine Wahrscheinlichkeit von 1/6. Wenn du mit zwei Würfeln würfelst und die Kombination betrachtest, sind sie immer noch gleichverteilt: Jede Kombination (wenn die Würfel markiert sind) hat eine Wahrscheinlichkeit von 1/36. Wenn du aber die Summe betrachtest, kriegst du eine Normalverteilung: 2 hat eine Wahrscheinlichkeit von 1/36 (genau wie 12), 7 aber zum Beispiel hat eine Wahrscheinlichkeit von 1/6. Da müsste ich mich schon sehr geirrt haben, wenn das plötzlich anders aussieht, bloß weil es um Integer geht.
Und naja, wenn ein Angreifer statt
Wahrscheinlichkeit Wahrscheinlichkeit
^ ^
| |
| | o°o
| | oo oo
|----------- |oo oo
+-----------> zahl das hier +-----------> zahl
kriegt, dann würde er natürlich zuerst die Zahlen aus der Mitte probieren. Zumal die Addition die Anzahl der Bits nicht vervielfältigt, sondern (wenn es wie vorgeschlagen 4 Zufallszahlen sind) nur 2 Bits davorhängt.
Da kenne ich den Code nicht, kann ich also nichts zu sagen.
Laut Doku soll man lieber mt_rand() benutzen, weil das schneller und besser als rand() ist.
--
Henryk Plötz
Grüße von der Ostsee
Moin Moin !
Ja? Wenn ich ein sleep(1) einbaue, dann braucht er egal wie schnell das ganze quer über das Internet funktioniert immerhin im Idealfall 1.125.899.906.842.624 Sekunden, macht über den Daumen noch ca. 35.702.051 Jahre. Oder habe ich mich jetzt grob verrechnet?
Selbst wennihc das weglasse, vermutlich schafft er ca. 100, max 200 Anfragen in der Sekunde, wenn ich davon ausgehe er schafft 1000 pro Sekunde, dann braucht er immer noch 35.702 Jahre!
und wenn ich dann noch ein sleep(2) einbaue(am besten nur dann wenns die Fehlermeldung gibt), dann wird es per Brute-Force vermutlich unmöglich - vor allem über das Internet, oder?
Das funktioniert aber nur bei einem wirklich blöden Angreifer, der schön brav eine ID nach der anderen ausprobiert. Mal sehen, ich könnte pro Rechner so um die 2^16 Ports zum Senden eines HTTP-Requests öffnen, daß muß ich beim Wertebereich von MD5 nur höchstens 2^128/2^16 = 2^112 mal machen. Das mache ich mit 2^4 (16) Rechnern gleichzeigtig, schon bin ich bei 2^108. Dein Webserver bekommt dann 2^20 Requests auf einen Schlag, macht die Grätsche, und ich kann für heute Feierabend machen. *<:o)
Alexander
Hi!
Das funktioniert aber nur bei einem wirklich blöden Angreifer, der schön brav eine ID nach der anderen ausprobiert. Mal sehen, ich könnte pro Rechner so um die 2^16 Ports zum Senden eines HTTP-Requests öffnen, daß muß ich beim Wertebereich von MD5 nur höchstens 2^128/2^16 = 2^112 mal machen. Das mache ich mit 2^4 (16) Rechnern gleichzeigtig, schon bin ich bei 2^108. Dein Webserver bekommt dann 2^20 Requests auf einen Schlag, macht die Grätsche, und ich kann für heute Feierabend machen. *<:o)
Besser die Grätsche machen als was veraten, außerdem sollte es da doch inzwischen Sicherheitsvorkehrungen geben, oder? Aber was bringen die soviele Requests, wenn mein Rechner über das Internet überhaupt nur in der Lage ist, ca. 100- max. 200 pro Sekunde zu beantworten? Und das ist schon vergleichbar viel!
Grüße
Andreas
ca. 10 User bekommen eine email mit dem Link zu der gegen alle anderen Cracker... und böswilligen User zu schützenden Seite.
Der link sieht so aus: http://www.server.de/seite.php?id=123&user_id=12312kj3lk12j39023j12lkj3lkj12
id bechränkt die zusammengehörigen User (ca. 10), und user_id ist ein MD5-String den ich wie folgt erzeuge(PHP):
srand ((double)microtime()*1000000);
$randvalue = rand();
$user_id = urlencode(md5($randvalue.$email_adresse));
Ich hatte mir das jetzt mal so gerechnet, wenn jemand anders die id errät(ist ja nicht ganz so schwer), dann braucht er viel Glück eine gültige user_id zu erraten:
Warum so kompliziert? Da kannst Du Dir auch eine bel. Zeichenkombination ausdenken.
MD5(...) ist genau so leicht oder schwer zu erraten wie
"j3uq91qmaidu8wjwshsgfgheu3h" was ich mal so eben selber tippe.
Sinn machen würde MD5 nur so:
Du und der User tauschen einen Secret Key aus (Telefon, PGP etc.).
Der User sendet Username und MD5($username . $secretkey).
Du checkst, ob Du bei MD5($username . $secretkey) dasselbe rausbekommst, wenn ja => authorisiert.
Und das ist auch die einzige Schwachstelle an der ganzen Sache, die Klartext-Email, aber das Problem wird man wohl immer haben, aber wenn jemand der ein Interesse hat da einzubrechen bereits in der Lage ist entweder bei mir oder bei dem betroffenen User emails mitzulesen ist eh fast alles verloren!
Jawoll.
Hi!
Warum so kompliziert? Da kannst Du Dir auch eine bel. Zeichenkombination ausdenken.
Ja, aber ich sitze nicht den ganzen Tage hinter dem Server um allen Leuten Ihre IDs zuzuweisen!
MD5(...) ist genau so leicht oder schwer zu erraten wie
"j3uq91qmaidu8wjwshsgfgheu3h" was ich mal so eben selber tippe.
Wenn Du nen Job brauchst? Ich wüßte da was...
Sinn machen würde MD5 nur so:
Du und der User tauschen einen Secret Key aus (Telefon, PGP etc.).
Der User sendet Username und MD5($username . $secretkey).
Du checkst, ob Du bei MD5($username . $secretkey) dasselbe rausbekommst, wenn ja => authorisiert.
Ja, aber das ist ja gar nicht mein Problem! Ich will doch ledigleich eine zufällige "SessionID" haben, aber nicht 1 pro Session, sondern 10 Stück auf einmal, da ich 10 Mails in einer Schleife versende! Aber vielleicht könnte ich die PHHPSESSID als srand() Wert verwenden, aber das ist auch nicht besser, oder?
Grüße
Andreas
Der größte Unsicherheitsfaktor ist wohl dennoch der User selbst...
Ob Du verschlüsselst oder nicht: Du versendest letztendlich eine große "Zufallszahl" und hoffst, dass diese nicht mittels brute- force- Angriff geknackt werden kann.
Übrigens: rein theoretisch müsste der brute- force Angriff nicht ein zehntel aller möglichenm Kombinationen durchspielen. Bei einer "gleichmäßigen" Verteilung der 10 passenden Schlüssel wäre es ein statistisch betrachtet ein zwanzigstel :)
fastix
Der größte Unsicherheitsfaktor ist wohl dennoch der User selbst...
Ob Du verschlüsselst oder nicht: Du versendest letztendlich eine große "Zufallszahl" und hoffst, dass diese nicht mittels brute- force- Angriff geknackt werden kann.
Und was hat das mit dem User zu tun? Der hat da doch NULL Einfluß drauf?!
Übrigens: rein theoretisch müsste der brute- force Angriff nicht ein zehntel aller möglichenm Kombinationen durchspielen. Bei einer "gleichmäßigen" Verteilung der 10 passenden Schlüssel wäre es ein statistisch betrachtet ein zwanzigstel :)
Immer noch ein vertretbares Risiko...
...das mit den Hexadezimal-Zahlen hat mich da mehr geschockt ;-)
Grüße
Andreas