Naps: Login Sicherheit erhöhen

Hi,

da md5 ja nicht mehr sicher ist hab ich mir mal was überlegt, und würde gerne eure Meinung dazu hören.

Das unsichere daran ist ja meines Wissens, dass mehrere verschiedene Nachrichten den selben Hash haben können.

Wenn ich jetzt aber in meiner DB fürs Login je den MD5 Hash und einen SHA Hash des Passworts speicher kann doch "fast" nur mehr das richtige Passwort stimmen!?

Sehe ich das so richtig?

MfG
Naps

  1. Hello,

    da md5 ja nicht mehr sicher ist hab ich mir mal was überlegt, und würde gerne eure Meinung dazu hören.

    Das unsichere daran ist ja meines Wissens, dass mehrere verschiedene Nachrichten den selben Hash haben können.

    Wenn ich jetzt aber in meiner DB fürs Login je den MD5 Hash und einen SHA Hash des Passworts speicher kann doch "fast" nur mehr das richtige Passwort stimmen!?

    Sehe ich das so richtig?

    Nein.
    Das wurde hier vor kurzem schon einmal ausführlich diskutiert. Schau bitte im Archiv nach.

    So, wie Du das beschreibst, entspreicht das einer Parallelschaltung. Der Widerstand, den es zu überbrüchen gilt, sinkt also.

    Der Gesamtwiederstand ist also kleiner, als der kleinste eingebaute.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hallo,

      Das wurde hier vor kurzem schon einmal ausführlich diskutiert. Schau bitte im Archiv nach.

      Link?

      So, wie Du das beschreibst, entspreicht das einer Parallelschaltung. Der Widerstand, den es zu überbrüchen gilt, sinkt also.
      Der Gesamtwiederstand ist also kleiner, als der kleinste eingebaute.

      Ich frage mich gerade wovon du sprichst ...

      Jeena

      1. Hi!

        Das wurde hier vor kurzem schon einmal ausführlich diskutiert. Schau bitte im Archiv nach.
        Link?

        Ich denke, der da war der betreffende Faden.

        So, wie Du das beschreibst, entspreicht das einer Parallelschaltung. Der Widerstand, den es zu überbrüchen gilt, sinkt also.
        Der Gesamtwiederstand ist also kleiner, als der kleinste eingebaute.
        Ich frage mich gerade wovon du sprichst ...

        Das Bild mit dem Widerstand zeigt durchaus gewisse Parallelen. Die elektrischen Gegebenheiten kann man unter den Stichwörtern Reihenschaltung und Parallelschaltung von Widerständen nachlesen. Hier geht es darum, dass der OP die Ergebnisse von zwei Verfahren speichert. Er hatte auch kein Salt vorgesehen. Der Angreifer hat nun von zwei Verfahren die Rainbow-Tabellen, in denen er nachschlagen kann. Wenn die eine den Wert nicht enthält, vielleicht hat die anderen ihn. Und je mehr Verfahren man hinzunimmt, desto höher wird die Wahrscheinlichkeit, dass in einer der Rainbowtabellen der Hash-Wert zu finden ist. Das dazu gefundene Urbild kann er nun zur Bestätigung mit den anderen Verfahren hashen und die Ergebnisse vergleichen. Das klappt nur dann nicht, wenn er statt des Urbilds eine Kollision gefunden hat. Ansonsten hat man durch die zwei Verfahren zwei Wege und nicht nur einen mit. Genau wie beim Strom hat man nun nicht zwei Stellen hintereinander zu passieren, sondern kann sich auf die beiden Wege aufteilen.

        Lo!

        1. Hallo,

          Der Angreifer hat nun von zwei Verfahren die Rainbow-Tabellen, in denen er nachschlagen kann. Wenn die eine den Wert nicht enthält, vielleicht hat die anderen ihn. Und je mehr Verfahren man hinzunimmt, desto höher wird die Wahrscheinlichkeit, dass in einer der Rainbowtabellen der Hash-Wert zu finden ist.

          Aah ok, jetzt fange ich an das Gleichniss zu verstehen, danke.

          Jeena

  2. Hi there,

    Das unsichere daran ist ja meines Wissens, dass mehrere verschiedene Nachrichten den selben Hash haben können.

    Das ist aber nichts md5-Spezifisches sondern liegt in der Natur der Sache. Wenn Du eine beliebige Bytefolge/Nachricht/etc. auf 32 Byte "eindampfst", muss es logischerweise beliebig viele Nachrichten geben, die den selben Hash erzeugen. Oder anders 'rum: Wenn jede beliebige (auch beliebig lange) Nachricht einen exklusiven einzigarten 32 Byte-Hash ergäbe, dann wäre das eine ungemein effiziente Form der Datenkompression; auf der anderen Seite könnte es dann auch nicht mehr Nachrichten überhaupt geben als mit einem 32 Byte-Wort Kombinationsmöglichkeiten. Das ist bei längeren Hashes natürlich prinzipiell nichts anderes...

    1. Hallo,

      Das ist aber nichts md5-Spezifisches sondern liegt in der Natur der Sache. Wenn Du eine beliebige Bytefolge/Nachricht/etc. auf 32 Byte "eindampfst", muss es logischerweise beliebig viele Nachrichten geben, die den selben Hash erzeugen.

      Moment, er dampft doch nicht die daten auf 32 Byte ein sondern produziert eine Checksumme der Daten um zu schauen ob sie verändert wurden oder nicht. Eine Checksumme kann durchaus viel kürzer sein als die daten selbst und trotzdem mit extrem hoher Wahrscheinlichkeit Aussagen über die Gleichheit machen, es kommt halt auf den Algorythmus drauf an der die Checksumme berechnet. Man sollte sich für Passwörter einen suchen der cryptographisch noch nicht geknackt wurde.

      Jeena

      1. Hi,

        es geht hier etwas der Sinn verloren, wenn du das, worauf sich Klawischnigg bezog, nicht mit zitierst. Ich habe mir erlaubt, es wieder hinzu zu fügen.

        Das unsichere daran ist ja meines Wissens, dass mehrere verschiedene Nachrichten den selben Hash haben können.

        Das ist aber nichts md5-Spezifisches sondern liegt in der Natur der Sache. Wenn Du eine beliebige Bytefolge/Nachricht/etc. auf 32 Byte "eindampfst", muss es logischerweise beliebig viele Nachrichten geben, die den selben Hash erzeugen.

        Moment, er dampft doch nicht die daten auf 32 Byte ein sondern produziert eine Checksumme der Daten um zu schauen ob sie verändert wurden oder nicht.

        Bei der Überprüfung eines Passwortes geht es nicht darum, Daten gegen Veränderung bzw. Manipulation abzusichern - sondern es geht darum zu überprüfen, ob der Nutzer ein gemeinsames Geheimnis kennt, um ihn darüber als zugriffsberechtigt auf einen bestimmten Inhalt/für eine bestimmte Aktion zu authentifizieren.

        Eine Checksumme kann durchaus viel kürzer sein als die daten selbst und trotzdem mit extrem hoher Wahrscheinlichkeit Aussagen über die Gleichheit machen

        Das hat aber wenig mit der Aussage oben zu tun.
        Ein Hashverfahren, dass „alle“ denkbaren Nachrichten auf einen begrenzten Wertebereich abbildet, muss Kollisionen produzieren.
        Das ist aber hinsichtlich der Sicherheit eines Authentifizierungsverfahrens nicht der Haupt-Schwachpunkt - sondern der Aufwand, der erforderlich ist, um *eine* Zeichenkette zu finden, die den gleichen Hashwert wie das eigentliche Passwort ergibt, bzw. die Wahrscheinlichkeit, mit der dies innerhalb einer bestimmten Zeitspanne möglich ist - weil diese Zeichenkette dann an Stelle des eigentlichen Passwortes verwendet werden kann.

        Und in *dieser* Hinsicht ist MD5 inzwischen nicht mehr state of the art, und andere, stärkere Hash-Verfahren sind deshalb zu bevorzugen.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
      2. Moin Moin!

        Moment, er dampft doch nicht die daten auf 32 Byte ein sondern produziert eine Checksumme der Daten um zu schauen ob sie verändert wurden oder nicht. Eine Checksumme kann durchaus viel kürzer sein als die daten selbst und trotzdem mit extrem hoher Wahrscheinlichkeit Aussagen über die Gleichheit machen,

        Nö. Der Vergleich zweier Prüfsummen sagt nur aus, dass die Ursprungsdaten ungleich sind, wenn die Prüfsummen ungleich sind. Bei identischen Prüfsummen können die Ursprungsdaten immer noch ungleich sein (Hash-Kollision).

        es kommt halt auf den Algorythmus drauf an der die Checksumme berechnet.

        Nein, das Problem bleibt. Prüfsummen-Vergleiche sagen nichts über Gleichheit aus, nur über Ungleichheit.

        Man sollte sich für Passwörter einen suchen der cryptographisch noch nicht geknackt wurde.

        Salz nicht vergessen!

        Der gängige Weg, salted Hashes, geht davon aus, dass Hash-Kollisionen innerhalb der relativ überschaubaren Menge aller zugelassenen Passworte sehr unwahrscheinlich sind, und nimmt das Risiko in Kauf, des es doch vielleicht einige Tupel von Passworten gibt, die den selben Hash-Wert haben. Benutzer, die so ein Passwort gewählt haben, können sich dann auch mit einem zweiten Passwort anmelden, dass den selben Hash-Wert liefert.

        Das pro Benutzer zufällig vergebene Salt-Wert sorgt dafür, dass ein Angreifer erstens nicht aus Hash-Wert und bekanntem Passwort eines Accounts (z.B. des eigenen) auf das Passwort eines anderen Accounts schließen kann, und zweitens verhindert der Salt-Wert den sinnvollen Einsatz von Rainbow-Tables.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  3. Moin Moin!

    Du suchst Hash-Kollisionen, d.h. zwei Strings / Passworte / Nachrichten, die trotz unterschiedlichem Inhalt den selben Hash-Wert haben.

    Wo ist nun das Problem?

    Das für zwei unterschiedliche Passworte der selbe Hash herauskommt, stört den User erst einmal gar nicht. Die Wahrscheinlichkeit, dass das bei der Änderung nur eines Zeichens (typischer Vertipper / Buchstabendreher) vorkommt, dürfte gegen Null gehen.

    Aber "ungesalzene" Passwort-Hashes haben ein anderes Problem. Rainbow-Tabellen. Dagegen helfen salted hashes, damit ergeben selbst identische Passworte unterschiedliche Hash-Werte.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  4. Danke erstmal an alle!

    ich arbeite bereits mit einem statischen Salt und einem inviduellen für jeden User der neben dem Passwort-Hash in der DB gespeichert wird.

    Mein Passwort wird derzeit so gebildet:

    md5($pass.$dbSalt.$staticSalt)

    Mir ging es aber bei meiner Frage eher darum ob es sicherer wäre wenn ich jetzt z.b. so was in der Art mache.

    Passwort: geheim

    $md5 = hash("md5", 'geheim'.$dbSalt.$staticSalt);
    $sha = hash("sha512", 'geheim'.$dbSalt.$staticSalt);

    in die DB werden nun beide eingetragen.

    Beim Login werden beide überprüft.

    Was ich damit erreichen will ist, dass selbst wenn man durch Einsatz von Rainbow-Tables ein Passwort finden würde das die selbe md5 Prüfsumme wie mein Passwort "geheim" besitzt immer noch die sha Prüfsumme da wäre.

    lg Naps

    1. Hi.

      $md5 = hash("md5", 'geheim'.$dbSalt.$staticSalt);
      $sha = hash("sha512", 'geheim'.$dbSalt.$staticSalt);

      in die DB werden nun beide eingetragen.

      Beim Login werden beide überprüft.

      Was ich damit erreichen will ist, dass selbst wenn man durch Einsatz von Rainbow-Tables ein Passwort finden würde das die selbe md5 Prüfsumme wie mein Passwort "geheim" besitzt immer noch die sha Prüfsumme da wäre.

      Eine Grundsatzüberlegung:

      • Jede Art von Passwortschutz bietet niemals eine absolute, sondern immer nur eine probabilistische Sicherheit: Dass jemand das Passwort rät oder sonstwie den Schutz aushebelt, ist *hinreichend*unwahrscheinlich*[1].

      • Ein guter Hash-Algorithmus muss[2] leisten, dass das Finden eines(!) Urbildes eines gegebenen Hashs durch einen Angreifer hinreichend unwahrscheinlich[1] ist. Sonst kann man ihn in den Müll werfen.

      • SHA-512 leistet das (nach jetzigem Stand der Dinge).

      • Was Du machst, ist Raterei: SHA-512 vertraust Du nicht, SHA-512 + MD5 (also die Konkatenation, d.h. ein 640-Bit-Hash) aber schon. Stell Dir vor, es gäbe schon einen SHA-640. Dann würdest Du ihm wieder nicht trauen und lieber einen SHA-640 + MD5 benutzen, oder? Das ist unsinnig. Wenn Du einen SHA-512 Hashwert speicherst, kannst Du davon ausgehen, dass ein Angreifer, der den Wert hat, kein einziges(!) Urbild davon finden wird, weder durch Raten noch auf andere Weise. Es ist hinreichend unwahrscheinlich[1].

      Alles weitere steht schon im Archiv.

      [1] in irgendeinem vernünftigen Sinne
      [2] je nach Verwendung ist das u.U. nicht mal notwendig

      Viele Grüße,
      der Bademeister

      1. Moin Moin!

        Hi.

        $md5 = hash("md5", 'geheim'.$dbSalt.$staticSalt);
        $sha = hash("sha512", 'geheim'.$dbSalt.$staticSalt);

        in die DB werden nun beide eingetragen.

        Beim Login werden beide überprüft.

        Was ich damit erreichen will ist, dass selbst wenn man durch Einsatz von Rainbow-Tables ein Passwort finden würde das die selbe md5 Prüfsumme wie mein Passwort "geheim" besitzt immer noch die sha Prüfsumme da wäre.

        • Was Du machst, ist Raterei: SHA-512 vertraust Du nicht, SHA-512 + MD5 (also die Konkatenation, d.h. ein 640-Bit-Hash) aber schon. Stell Dir vor, es gäbe schon einen SHA-640. Dann würdest Du ihm wieder nicht trauen und lieber einen SHA-640 + MD5 benutzen, oder? Das ist unsinnig. Wenn Du einen SHA-512 Hashwert speicherst, kannst Du davon ausgehen, dass ein Angreifer, der den Wert hat, kein einziges(!) Urbild davon finden wird, weder durch Raten noch auf andere Weise. Es ist hinreichend unwahrscheinlich[1].

        Es ist noch schlimmer: MD5 ist mit überschaubarem Aufwand knackbar, d.h. man findet relativ einfach das Passwort oder ein kleines Set von Passworten mit identischem MD5-Hash. Und dank der zusätzlichen Frickelei mit SHA512 ist es nun extrem leicht zu prüfen, ob das zurückgerechnete Passwort korrekt ist bzw. welches aus dem Set das passende ist -- ganz einfach indem man darüber den SHA512-Hash berechnet und mit dem vorhandenen Sollwert berechnet, das geht auf aktueller Hardware mit lächerlich geringem Aufwand. Ein Angreifer muß sich also gar nicht am härteren SHA512 abrackern. Erleichtert wird dem Angreifer die Arbeit auch noch dadurch, dass MD5 und SHA512 exakt den selben String verarbeiten, mit identischem Salt. Das wäre für die doppelte Passwort-Püfung überhaupt nicht nötig, beide Hash-Funktionen könnten mit unterschiedlichen Salt-Werten arbeiten.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
        1. Hi Alexander.

          Es ist noch schlimmer: [...] dank der zusätzlichen Frickelei mit SHA512 ist es nun extrem leicht zu prüfen, ob das zurückgerechnete Passwort korrekt ist [...]

          Ja stimmt, wenn der Angreifer die Hash-Werte hat, dann ist SHA + MD5 also sogar erheblich schlechter als SHA (wenn auch etwas besser als MD5, sofern Salts richtig verwendet werden). Danke.

          Nur wenn es ums Erraten von Urbildern geht (wenn also kein Hash-Wert bekannt ist), ist es überhaupt technisch gesehen etwas besser, aber immer noch unnötig.

          Viele Grüße,
          der Bademeister

  5. Noch, was anderes was mir so durch den Kopf gegangen ist:

    wie schaut es aus wenn man es so macht:

    Passwort = "hallo"

    jetzt zerteil ich das ganze in einzelne Zeichen und erzeuge den Hash:

    md5('h') = '2510c39011c5be704182423e3a695e91';
    md5('a') = '0cc175b9c0f1b6a831c399e269772661';
    md5('l') = '2db95e8e1a9267b7a1188556b2013b33';
    md5('l') = '2db95e8e1a9267b7a1188556b2013b33';
    md5('o') = 'd95679752134a2d9eb61dbd7b91c4bcc';

    dann md5('2510c39011c5be704182423e3a695e91'.'0cc175b9c0f1b6a831c399e269772661'.'2db95e8e1a9267b7a1188556b2013b33'.'2db95e8e1a9267b7a1188556b2013b33'.'d95679752134a2d9eb61dbd7b91c4bcc');

    ergibt mir dann '6bb3a94294dfb5e4932c5299c0f4425c'; als meinen endgültigen Hash.

    lg Naps

    1. Moin Moin!

      Umständlich, aber nicht sicherer. Gegen Rainbow-Tables hilft der Ansatz, das Passwort zu verwursten, allerdings wird das Ergebnis nicht besser:

      Du verteilst die 8 Bit jedes Zeichens auf 128 Bit einer MD5-Summe, aber trotzdem bekommst Du nur 256 verschiedene MD5-Summen. Und weil die bei PHP als hexadezimale Zahlen aus der MD5-Funktion herausfallen, sind in dem String sehr viele Bits konstant 0 oder konstant 1. Die zehn dezimalen Ziffern unterscheiden sich nur in 4 Bit, die sechs zusätzlichen Buchstaben sogar nur in 3 Bit voneinander. Das Zusammenkleben der einzelnen MD5-Summen erzeugt so zwar eine große Menge Bits, die sind aber überwiegend konstant. Damit wird die Ergebnismenge der finalen MD5-Summe KLEINER, die Wahrscheinlichkeit für Kollisionen STEIGT also.

      Und für gleiche Passworte spuckt diese sinnfreie Verbrennung von Rechenleistung immer noch gleiche MD5-Summen aus.

      Best Practice / Stand der Technik ist SHA512 mit einem zufälligen Salt-Wert pro Benutzer, irgendwann in naher Zukunft wird es eine andere Hash-Funktion gebeb, die SHA512 überlegen ist. Wenn Du nicht SEHR, SEHR viel Erfahrung mit kryptographischen Hashfunktionen hast (und damit ist die Entwicklung solcher Funktionen gemeint und nicht ihre Nutzung), solltest Du Dich daran halten, statt selbst irgendetwas zusammenzufrickeln, was am Ende noch viel angreifbarer ist als ungesalzenes MD5.

      Noch besser wäre natürlich, zugunsten von Public-Key-Verfahren auf Passworte komplett zu verzichten. Das ist im Web-Umfeld allerdings noch nicht wirklich praktikabel.

      Leseempfehlung: http://aktuell.de.selfhtml.org/weblog/php-verschluesselung-100-euro-wette (Ja, da geht es um Verschlüsselung, nicht um Hash-Funktionen. Beide sind aber mathematisch ausreichend eng verwandt, um daraus auch für Hash-Funktionen eine Lehre zu ziehen.)

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".