Frage zu hashalgorithmen(md5, sh1, etc.)


  • 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...


  • Mod

    PHPNewbie schrieb:

    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.

    So ist es.



  • Ok, hab jetzt auch das symmetrische Verfahren implementiert.
    D.h. ich hole mir erst den PublicKey vom server, generiere einen symmetrischen schlüssel beim Client und schicke diesen dann verschlüsselt mit dem PublicKey zum server.

    Zur Man in the middle Problematik:

    [quote=SeppJ]Denn eigentlich müssten sich die beiden Kommunikationspartner dafür zuvor irgendwo persönlich getroffen haben und Geheimnisse (Zertifikate) ausgetauscht haben. [/quote]

    Genau das halte ich für meine Anwendung einfach für unlösbar. Wie soll ich das bitte machen? Irgendwann muss der Client runtergeladen werden und die Quelle muss vertrauenswürdig sein. Da es sich aber um eine Flash .swf Datei handelt die auf vielen verschiedenen Webseiten eingebunden werden soll(wie ein Video eben) geht das einfach nicht.

    Da stelle ich mir auch gleich die Frage, ob der Browser den ich nutzte nicht auch schon aus einer Quelle stammt die nicht vertrauenswürdig ist und somit schon Kompromittiert ist und die Zertifikatliste die er enthält nutzlos ist.

    Wie soll ich das Lösen?


  • Mod

    PHPNewbie schrieb:

    Da stelle ich mir auch gleich die Frage, ob der Browser den ich nutzte nicht auch schon aus einer Quelle stammt die nicht vertrauenswürdig ist und somit schon Kompromittiert ist und die Zertifikatliste die er enthält nutzlos ist.

    Wie soll ich das Lösen?

    Gar nicht. Das CA-System ist nicht gut, aber es ist wohl, worauf du dich in der Praxis einlassen müsstest.



  • PHPNewbie schrieb:

    D.h. ich hole mir erst den PublicKey vom server, generiere einen symmetrischen schlüssel beim Client und schicke diesen dann verschlüsselt mit dem PublicKey zum server.

    Das ist nicht sicher gegen Replay-Angriffe, btw.



  • Nicht? Wenn ich mein gehashtes Passwort mit dem symmetrischen schlüssel versehe und dann verschicke, dann bringt der replay Angriff doch nichts mehr, weil bei der nächsten Session ja wieder ein anderer symmetrischer Schlüssel verwendet wird, entspricht das nicht schon der "Nonce"?


  • Mod

    PHPNewbie schrieb:

    Nicht? Wenn ich mein gehashtes Passwort mit dem symmetrischen schlüssel versehe und dann verschicke, dann bringt der replay Angriff doch nichts mehr, weil bei der nächsten Session ja wieder ein anderer symmetrischer Schlüssel verwendet wird, entspricht das nicht schon der "Nonce"?

    Was hindert denn den Angreifer, die exakt gleichen Schritte zu wiederholen? Für den Server sieht das so aus, als wäre der Schlüssel eben beide Male der gleiche.



  • Ok, ich habe jetzt noch die nonce gegen Replay-Angriffe implementiert. Bin mir aber nicht sicher ob ich alles richtig gemacht habe. Ich liste mal meine schritte auf:

    1.) Client: requestPublicKey();
    2.) Server: Session starten, Keypaar erzeugen, private key merken, public key zurücksenden
    3.) Client: Public key erhalten, symmetrischen schlüssel generieren, symmetrsichen Schlüssel mit erhaltenem public key verschlüsseln und abschicken.
    4.) Server: symmterischen Schlüssel aus Nachricht mittles privaten key extrahieren, nonce generieren, nonce mit symmetrischen schlüssel verschlüsseln und abschicken.
    5.) Client: nonce extrahieren, cnonce generieren, passwort hashen. nonce, cnonce, username und hashedPasswort konkatenieren und das ergebnis hashen. cnonce, username, hashedPasswort und hashedPasswordWithNonce verschlüsseln und abschicken.
    6.) Server: daten entschlüsseln und hashedPasswordWithNonce verifizieren, dann hashedPassword mit datenbank abgleichen. User ggf. auf eingeloggt setzen, nonce löschen.

    Jetzt müsste ich noch an geeigneter stelle prüfen ob der User schon eingeloggt ist, am besten vor 1.)? Hmm, zudem Speicher ich den Login status im Moment nur in der $_SESSION, sollte besser in die Datenbank oder?

    Ich weis ist viel Text, wäre aber schön wenn Jemand das kurz prüfen kann und mir Verbesserungsvorschläge/Korrekturen gibt.

    Das was bisher von euch gekommen ist war schon super! Danke!


  • Mod

    Wenn du tatsächlich jedes Mal wieder einen neues Schlüsselpaar auf dem Server erzeugen möchtest, dann kann das auch als Nonce dienen, und dein vorheriges Vorhaben macht mehr Sinn. Aber wie identifiziert der Client dann den Server? Und wie lange braucht das Erzeugen der Schlüsselpaare?


Anmelden zum Antworten