Frage zu hashalgorithmen(md5, sh1, etc.)



  • Hi!

    Ich tüftel gerade an ein Login System von Flash(as3) nach php.
    Ich habe bisher nachgelesen, dass man Passwörter(der User) nicht als Klartext in eine Datenbank speichert, damit falls die Datenbank "gestohlen" wird die Diebe nichts damit anfangen können. Dazu habe ich Verständnisfragen:

    In der Datenbank sind ja nicht nur die Passwörter drin sondern auch der usernamen, wenn ich nun den Usernamen und sein gehashtes passwort habe, kann ich dann nicht einfach eine Zeichenkette erstellen die denselben Hash generiert und diese dann als pseudo-passwort verwenden? Mein Gedanke dazu war: "Das ist nicht möglich, weil zu rechenintensiv".

    Aber dann frage ich mich doch, wenn ein Hashalgorithmus bekannt ist, dann kann man doch im voraus für jeden Hash eine Zeichenkette erstellen, abspeichern und später dann nach dem hash suchen den man braucht und bekommt damit ein Passwort das verwendet werden kann. 2^40 (für sha1) mögliche hashes ist zwar 'ne menge, aber einmal generiert, einfach wiederzuverwenden. Wobei 2^40 nun auch nicht so viel sind, eine Datenbank mit mehreren Terrabytes würde für jeden hash ein pseudo-Passwort haben. Wo ist mein Denkfehler?



  • ah, hab 2^40 bits gedacht, tatsächlich sind es aber 40 stellen die alphanumerisch sind. Das würde einiges erklären.



  • PHPNewbie schrieb:

    2^40 (für sha1) mögliche hashes ist zwar 'ne menge, aber einmal generiert, einfach wiederzuverwenden. Wobei 2^40 nun auch nicht so viel sind, eine Datenbank mit mehreren Terrabytes würde für jeden hash ein pseudo-Passwort haben. Wo ist mein Denkfehler?

    Abgesehen davon vielleicht schau mal
    http://de.wikipedia.org/wiki/Rainbow_Table
    an.
    Zur Zeit reichts, wenn man als User einen Umlaut reinmacht, weil die großen mit 10000 zusammenarbeitenden Rechnern erstellten RainbowTables keine Umlaute drin haben. Du als Admin kannst einen Umlaut in den Salt oder Pepper tun, *hihi*.



  • PHPNewbie schrieb:

    2^40 (für sha1) mögliche hashes ist zwar 'ne menge, aber einmal generiert, einfach wiederzuverwenden. Wobei 2^40 nun auch nicht so viel sind, eine Datenbank mit mehreren Terrabytes würde für jeden hash ein pseudo-Passwort haben. Wo ist mein Denkfehler?

    Wie volkard schon sagte: Das gibts nennt sich Rainbowtable.
    Und das ist dummerweise sogar ganz gut machbar, denn es gibt eine Reihe von "Standardpasswörtern", die viel zu viele Leute verwenden. Hat man die in den Tables, kommt man schon an ziemlich viele Hashes dran.



  • Nachtrag: Der Artikel http://de.wikipedia.org/wiki/Rainbow_Table spricht immer von "unwirtschaftlich". Das ist kein Witz, sondern eine sehr sehr ernste Sache.

    Also sagen wir mal Du hast ein Rechnerding kryptografisch abgesichert und wenn jemand es knackt, gewinnt er 100Mio€ oder bekommt Nacktvideos vom Merkel oder sowas, Was macht er dann?

    a) Er kauft sich für 10Mio€ Hardware, nimmt sich ein Jahr Zeit (die ich mal mit 100k€ rechne), veralbert 100Hochschulabgänger (1Mio€) (typische externe Diplomarbeit "Entwickeln Sie eine automatische Steuerung für Omnibusse." mit Nachtrag nachdem man sinnvoll abbrechen kann "Sie muss auch Omnibusse in geringer Flughöhe in Überschallgeschwindigkeit steuern können.")

    b) Er mietet für 100k€ einen Griechen, der mit seinem Team Deine gesamte Familie entführt und noch Porto in Höhe 0.62€ für einen Brief an Dich.

    Es ist Quatsch, immer die total sichere Lösung zu nehmen. Vielleicht reicht AES und man braucht keine teure Vollbitverschlüsselung.





  • Die korrekte Lösung um Passwörter zu speichern wäre bcrypt oder scrypt. In PHP gibts mit password_hash() und password_verify() schon bcrypt eingebaut.

    SHA-1 hat übrigens 160 Bit, die eben als Hexadezimalziffern ausgegeben werden.



  • Ok, danke erstmal. Jetzt ist mir schonmal klar warum man das mit hashes macht und warum es relativ sicher ist. Ich habe jetzt auch nicht vor ein super-dupa sicheres system aufzubauen, aber Passwörte im Klartext speichern wollte ich dann nun auch nicht. Das genannte bcrypt für php sieht nach der besten(und einfachen) Lösung aus.

    Jetzt brächte ich nur noch was um die Login daten sicher zum webserver zu bekommen. Da habe ich dann auch gelesen, dass man das über https machen würde. Und hier habe ich wieder fragen:

    https wurde entwickelt um zu verhindern das ein "lauscher" zwischen server und client sensible daten abfängt und missbraucht, richtig?

    Wenn man nun die daten verschlüsselt überträgt, dann kann der lauscher nichts damit anfangen, ähnlich wie beim Datenbank klau der gehashten passwörter.

    Und jetzt die Frage: Wie verhindert man denn, dass der lauscher den schlüssel zum dekodieren nicht bekommt? Wenn der lauscher doch alles mitschneiden kann, dann doch auch anfängliche Übertragung des Schlüssels, oder?


  • Mod

    PHPNewbie schrieb:

    Ok, danke erstmal. Jetzt ist mir schonmal klar warum man das mit hashes macht und warum es relativ sicher ist. Ich habe jetzt auch nicht vor ein super-dupa sicheres system aufzubauen, aber Passwörte im Klartext speichern wollte ich dann nun auch nicht. Das genannte bcrypt für php sieht nach der besten(und einfachen) Lösung aus.

    Ein bisschen sicher gibt's nicht. Entweder dein System ist nach allen Regeln der Kunst gesichert oder du kannst es gleich gänzlich offen lassen. Alles dazwischen ist nur das Vortäuschen falscher Sicherheit.

    Jetzt brächte ich nur noch was um die Login daten sicher zum webserver zu bekommen. Da habe ich dann auch gelesen, dass man das über https machen würde. Und hier habe ich wieder fragen:

    https wurde entwickelt um zu verhindern das ein "lauscher" zwischen server und client sensible daten abfängt und missbraucht, richtig?

    Ja.

    Wenn man nun die daten verschlüsselt überträgt, dann kann der lauscher nichts damit anfangen, ähnlich wie beim Datenbank klau der gehashten passwörter.

    Ja.

    Und jetzt die Frage: Wie verhindert man denn, dass der lauscher den schlüssel zum dekodieren nicht bekommt? Wenn der lauscher doch alles mitschneiden kann, dann doch auch anfängliche Übertragung des Schlüssels, oder?

    Es ist leicht möglich, sich auf einen Schlüssel zu einigen, ohne diesen jemals offen zu kommunizieren. Das einfachste Beispiel dafür ist ein asymmetrisches Verfahren, bei dem die beiden Partner einfach zu erst (offen) ihre öffentlichen Schlüssel austauschen und sich mittels dieser dann auf einen Schlüssel für ein (weniger rechenintensives) symmetrisches Verfahren einigen.

    Das eigentliche Problem hast du aber ganz übersehen: Woher weißt du, dass der Gegenüber auch der ist, den du erwartest und nicht jemand, der bloß vor gibt, dein Gegenüber zu sein? Die Antwort darauf ist leider höchst unbefriedigend. Denn eigentlich müssten sich die beiden Kommunikationspartner dafür zuvor irgendwo persönlich getroffen haben und Geheimnisse (Zertifikate) ausgetauscht haben. Für globale Kommunikation ist dies höchst unpraktisch. Die "Lösung" die man sich hat einfallen lassen ist, dass es eine Reihe von Einrichtungen (Zertifizierungsstellen) gibt, bei denen man sich Zertifikate ausstellen lassen kann und die dann idealerweise die Identität derjenigen prüfen, die sich das Zertifikat ausstellen lassen. Die Hersteller von Kommunikationssoftware (also unter anderem Browsern) haben eine Liste von Zertifizierungsstellen, denen sie vertrauen. Von denen bekommen sie entsprechende Zertifikate, die sie in ihre Software einbauen, mit denen diese prüfen kann, ob das Zertifikat, das ein Kommunikationspartner präsentiert auch echt ist. Du vertraust dem Browserhersteller, dass er nur gute Zertifizierungsstellen wählt*. Der Zertifizierungsstelle wird getraut, dass sie ihre Arbeit ordentlich macht. Und dem letztlichen Kommunikationspartner muss vertraut werden, dass er sich nicht sein Zertifikat hat klauen lassen. Eine ziemlich lange Kette von Vertrauen und wenn nur einer schludert, ist alles hin. Leider passiert dies sogar ziemlich oft. Gerade die Zertifizierungsstellen sind andauernd von Schlamperei betroffen. Gerade heute gibt es wieder eine große Meldung. Wobei man sich in diesem Fall streiten kann, welche der Parteien schuld ist. Aber das ändert nichts an der Verwundbarkeit des Verfahrens, sondern zeigt noch einmal, dass dieses System verwundbar an jeder einzelnen Stelle ist. Dass das ganze System geheimdienstlich unterwandert ist, ist ebenfalls so gut wie sicher.

    *: Und natürlich dir selber, dass du vertrauenswürdige Software gewählt hast und auch dass dein Computer keiner Weise kompromittiert ist.



  • Gut, hab vieles gelernt und zumindest die Prinzipien verstanden. Hab auch ein anschauliches Beispiel für das von dir erwähnte asymmetrische Verfahren gefunden.


  • Mod

    PHPNewbie schrieb:

    Gut, hab vieles gelernt und zumindest die Prinzipien verstanden. Hab auch ein anschauliches Beispiel für das von dir erwähnte asymmetrische Verfahren gefunden.

    Ok. Die Analogie passt. Ich ging davon aus, dass wir auf einem etwas höherem Niveau diskutieren. Mein Text richtete sich nicht unbedingt an Leute, die gar keine Kenntnisse zum Thema haben. Wenn du Fragen hast, kann ich Dinge auch einfacher erklären.



  • Muss nochmal nachhaken:

    hab auf wikipedia nachgelesen, dass man üblicherweise asymmetrisch und symmetrisch verschlüsslelt. Asymmetrisch, damit man überhaupt (kurzfristig?) geheime informationen(Sessionkey) austauschen kann und symmetrisch(weil schneller) damit man die Nutzdaten austauschen kann. Dabei beziehe ich mich auf diese
    Erläuterung.

    Meine Frage: Das ganze funktioniert solange die asymmetrische verschlüsselung nicht geknackt wurde oder? Würde ein Angreife alle daten mitlauschen und die asymmetrische verschlüsselung knacken(z.B. 2 wochen später), dann hätte dieser alle Daten oder? Was hat es mit dem Sessionkey auf sich? Da blick ich noch nicht durch.



  • PHPNewbie schrieb:

    Das ganze funktioniert solange die asymmetrische verschlüsselung nicht geknackt wurde oder? Würde ein Angreife alle daten mitlauschen und die asymmetrische verschlüsselung knacken(z.B. 2 wochen später), dann hätte dieser alle Daten oder?

    Ja.

    PHPNewbie schrieb:

    Was hat es mit dem Sessionkey auf sich? Da blick ich noch nicht durch.

    A muss zu Anfang den öffentlichen Key vom B haben.
    (Falls nicht, dann muss B diesen Key erstmal an A schicken. Was auch gleich die grösste Schwachstelle ist, denn A hat dabei üblicherweise keine gute Möglichkeit sicherzustellen dass der Key wirklich von A und nicht von einem sog. "Man in the Middle" kommt. Der einfachkeit halber gehe ich im Weiteren davon aus dass es keinen "Man in the Middle" gibt.)

    A erzeugt jetzt einen zufälligen Key mit passender Länge für das symmetrische Verschlüsselungsverfahren. Das ist der Session Key.

    Diesen Session Key verschlüsselt A mit dem öffentlichen Schlüssel von B (also mit dem asymmetrischen Verfahren), und schickt den verschlüsselten Session Key dann an B.
    Da zum Entschlüsseln der private Schlüsselteil nötig ist, kann B, und nur B, den Session Key entschlüsseln.

    Jetzt haben A und B also beiden einen Key den sonst keiner hat, der passend gross für ein symmetrisches Verfahren ist.

    Und genau diesen Key verwenden beiden dann um eben den eigentlichen Datenaustausch ("die Session") mit dem symmetrischen Verfahren zu verschlüsseln.

    Der Sinn dahinter: symmetrische Verschlüsselungsverfahren sind immens viel schneller als asymmetrische. Also will man die Nutzdaten symmetrisch verschlüsseln. Gleichzeitig sind aber asymmetrische Verfahren so praktisch. Also kombiniert man beide.



  • Danke, die Erklärung leuchtet ein. Dann müsste es doch aber reichen den Sessionkey einmal verschlüsselt rüberzuschicken?(Daher wohl auch der name "Session", weil pro login-"Session" ein key generiert wird?) Warum sieht das in den Wikipediabildchen so aus als würde für jede kommunikation ein neuer Sessionkey generiert werden?



  • Klar reicht ein Sessionkey pro Session. (Bzw. besser zwei, einer pro Teilnehmer.)



  • Ok, ich habe jetzt den asymeterischen teil implementiert.
    Ich sende mit meinem Flashclient eine Anfrage an eine publicKeyRequest.php.
    Auf der PHP seite generiere ich dann ein Schlüsselpaar mit OpenSSL und senden den Public key im PEM format an den Client zurück.

    Jetzt muss ich noch mit dem Client einen symmetrischen Schlüssel erstellen und mit dem publickey versehen, richtig? Welches verfahren wäre denn praktisch(bibliothek o.ä. vorhanden in as3/php) und sicher? Hab was von AES, TwoFish, Blowfish gelesen...

    Und wenn ich schon dabei bin, kann ich auch gleich ran machen die Man in the Middle problematik zu lösen.
    Geht das indem ich einfach den Public Key einmalig generiere und dann in meinem Client fest implementiere? Und den Private key auf dem Server sicher in eine Datei ablege? Damit entfällt dann auch der publicKeyRequest, oder?


  • Mod

    PHPNewbie schrieb:

    Geht das indem ich einfach den Public Key einmalig generiere und dann in meinem Client fest implementiere?

    Wie kommt der Client zum Anwender?



  • Der Client ist eine Flash datei(.swf) die direkt vom Browser aus aufgerufen wird und dann rutnergeladen wird(gecached?).


  • Mod

    PHPNewbie schrieb:

    Der Client ist eine Flash datei(.swf) die direkt vom Browser aus aufgerufen wird und dann rutnergeladen wird(gecached?).

    So konkret wollte ich das eigentlich gar nicht wissen. Aber es gibt sicherlich einen Grund, warum ich in diesem Kontext diese Frage gestellt habe. Denk mal darüber nach.



  • Hmmm, ok. Nehmen wir an der Public key sei im Clienten drin, der Man in the middle könnte den Clienten abfischen bevor er zum Anwender kommt und somit den public key manipulieren/ersetzen -> Also gleiche Problem wie als wenn der Server direkt den public key schickt. Aber auch schwieriger, da der Man in the middle ja jetzt erstmal den Clienten zerpfücken müsste(aber irrelevant?). Ich denke du willst auf die Zertifikate aus, womit ich mich noch garnicht beschäftigt habe..., so ein Aufwand..., nagut ich guck mal Zertifakte und so...


Log in to reply