bobby: Bewertung Passworthashmethode

Moin,

Kurze Frage. Ich verwende eine Hashfunktion in PHP um Passwörter in einer Datenbank zu hinterlegen. Dabei ist ein Benutzername, ein Passwort vom User, sowie ein SALT direkt vom Server einbezogen (also 2 Quellen zur Hasherzeugung)

Ich verwende einen Mix aus Whirlpool sha512 und bcrypt. Die Hashes kommen im folgenden Format (bcrypt):

$2y$14$Ra/qTjcQ9v1ZqL8kEavL/uXepTnolrMxwRoey9FgRQj6sSuo2jKQX

(Achtung, Hash habe ich verändert, damit ist dieser nicht gültig)

Ist die Methode grundsätzlich sicher? Selbstverständlich speichere ich das Passwort nirgends plain ab und ich habe für das Loginscript ein Schutz vor Brute-Force eingebaut.

Ich bitte einfach um eine kurze Bewertung.

Gruß Bobby

--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  1. hallo

    Ist die Methode grundsätzlich sicher? Selbstverständlich speichere ich das Passwort nirgends plain ab und ich habe für das Loginscript ein Schutz vor Brute-Force eingebaut.

    kommt darauf an... Wenn ich das Session-Token stehlen kann, kann mir deine Login-Sicherheit egal sein.

    So nebenbei: das Verketten von mehr Hash-Algorithmen macht einen Hash nicht besser. so man sowas tut, weil man befürchtet, dass der eine Algorithmus Entropie vernichtet, so kann diese nicht wieder restauriert werden durch einen anderen Algorithmus.

    1. Hello,

      Ist die Methode grundsätzlich sicher? Selbstverständlich speichere ich das Passwort nirgends plain ab und ich habe für das Loginscript ein Schutz vor Brute-Force eingebaut.

      kommt darauf an... Wenn ich das Session-Token stehlen kann, kann mir deine Login-Sicherheit egal sein.

      Darum sollte man ja den Betrieb auch nur über TLS (HTTPs) zulassen.

      Allerdings kann man dann immer noch Session-Token-Raten im Bruteforce fahren. Kommt dann eben darauf an, wie breit die gestreut sind über den Wertebereich und welche Maßnahmen ich am Server dagegen unternommen habe, die Attacke zu erkennen. Durch IPv6 ist das nur noch schwer möglich. Der Präfix sollte zwar i. d. R. dann gleich bleiben, aber wer weiß das schon genau?

      Wenn das System also viele User hat mit aktiven Sessions, ist die Wahrscheinlichkeit nicht ganz so gering, mal eine davon zu treffen. Ich hatte das hier neulich erst thematisiert, nachdem ich die Aufgabe bekommen hatte, gegen diese Lücke etwas zu tun. Ist leider nicht einfach, denn Session-Token-Raten geht am Loginsystem total vorbei.

      Liebe Grüße
      Tom S.

      --
      Es gibt nichts Gutes, außer man tut es
    2. Moin,

      kommt darauf an... Wenn ich das Session-Token stehlen kann, kann mir deine Login-Sicherheit egal sein.

      Session ID wird ständig gewechselt. Per URL kann keine SESSID gesetzt werden (nur Cookies). Zusätzlich sichere ich über HTTPS und SANITY-KEY ab. SESSION-HiJacking ist somit recht unwahrscheinlich. Aber danke für den Einwurf.

      So nebenbei: das Verketten von mehr Hash-Algorithmen macht einen Hash nicht besser. so man sowas tut, weil man befürchtet, dass der eine Algorithmus Entropie vernichtet, so kann diese nicht wieder restauriert werden durch einen anderen Algorithmus.

      Nein. Sowas tut man zum Beispiel um Hashes rotieren zu lassen 😉

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Hello,

        Wenn ich das Session-Token stehlen kann, kann mir deine Login-Sicherheit egal sein.

        Session ID wird ständig gewechselt.

        Das hört spätestens dann auf, lustig zu sein, wenn man mit AJAX arbeitet und manche Requests etwas länger unterwegs sind.

        Besser ist es tatsächlich, verschlüsselt zu arbeiten und ein zweites Credential mitzuführen (Extra-Cookie). Dann kann man, auch wenn eine Session zufällig|absichtlich getroffen wird, immer noch erkennen, dass etwas nicht stimmt. Da der Cookie in der Payload liegt, ist er vor dem Zugriff unterwegs sicher. Und die Wahrscheinlichkeit, dass man zeitnah auch den Cookie errät passend zum Session-Token ist tatsächlich sehr unwahrscheinlich, da der namensraum der Session alleine dem Affektierten User gehört, also keine Streudichte berücksichtigt werden muss.

        Bei Verschlüsselung, Session-Tokens und Extra-Cookie zählt also in der Hauptsache immer die Zeit und dann der Weertebereich und die Anzahl erlaubter Versuche.

        Liebe Grüße
        Tom S.

        --
        Es gibt nichts Gutes, außer man tut es
        1. Moin,

          Besser ist es tatsächlich, verschlüsselt zu arbeiten und ein zweites Credential mitzuführen (Extra-Cookie). Dann kann man, auch wenn eine Session zufällig|absichtlich getroffen wird, immer noch erkennen, dass etwas nicht stimmt.

          Ähm. Das macht doch aber der SANITY-KEY. der ist doch eben gerade dazu da, um ein versehentliches Treffen einer Session mit verschiedenen Werten abzugleichen und dann zu entscheiden ob tatsächlich der einstige Sessionnutzer am anderen Ende sitzt.

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          1. Hello,

            Besser ist es tatsächlich, verschlüsselt zu arbeiten und ein zweites Credential mitzuführen (Extra-Cookie). Dann kann man, auch wenn eine Session zufällig|absichtlich getroffen wird, immer noch erkennen, dass etwas nicht stimmt.

            Ähm. Das macht doch aber der SANITY-KEY. der ist doch eben gerade dazu da, um ein versehentliches Treffen einer Session mit verschiedenen Werten abzugleichen und dann zu entscheiden ob tatsächlich der einstige Sessionnutzer am anderen Ende sitzt.

            Der Begriff hat mir nicht gleich etwas gesagt. Bei mir heißt der immer "Fingerprint". Aber im Prinzip ist das ja schon so etwas ähnliches, nur dass er doch noch erheblich leichter erratbar ist, als eine Zufallszeichenfolge.

            Wie baust Du den und welchen Teil davon sendest Du wie dem Client?

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            1. Moin,

              Aus verschiedenen Umgebungsvariablen des Users mit einem Zufälligen Code des Servers gesaltet. Das ganze wieder über eine Hashfunktion geschickt. Das ganze wird bei jedem Session-Aufruf verifiziert. Sollte der Fingerprint nicht stimmen, wird die session sofort zerstört.

              Gruß Bobby

              --
              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
              1. Hello,

                Aus verschiedenen Umgebungsvariablen des Users mit einem Zufälligen Code des Servers gesaltet. Das ganze wieder über eine Hashfunktion geschickt. Das ganze wird bei jedem Session-Aufruf verifiziert. Sollte der Fingerprint nicht stimmen, wird die session sofort zerstört.

                Klonk (das war der Groschen).

                Der Salt steht nicht in der Session. In der Session steht nur der gehashte oder gecryptete Fingerprint. Ist schon ganz schön paranoid, aber scheinbar heutzutage notwendig. Ich werde da manchmal von Leuten (IHK, Verklagte) um Hilfe gebeten, denen man Missbrauch vorwirft und die es meistens nicht gewesen sind. Die Systeme müssen dann offengelegt werden, was die Betreiber aber ungern wollen. Damit sind die Verklagten dann meistens raus aus der Sache...

                Ich sammele daher derartig "einfache" Angriffsmethoden. Die Entscheider (Chefs, Gerichte, auch "Sachverständige") sind da alle noch zu technikhörig/-blauäugig. Die glauben immer, alles sei sicher, nur weil sie Passworte regelmäßig wechseln.

                Liebe Grüße
                Tom S.

                --
                Es gibt nichts Gutes, außer man tut es
                1. Moin,

                  Der Salt steht nicht in der Session. In der Session steht nur der gehashte oder gecryptete Fingerprint.

                  richtig. Es steht nur der gehashte Sanity-Key in der Session, der aus Uservariablen und dem Salt gebildet wird.

                  Ist schon ganz schön paranoid, aber scheinbar heutzutage notwendig.

                  Ja ist es. Ich habe mir da auch lange Gedanken drum gemacht.

                  Gruß Bobby

                  --
                  -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
        2. hallo

          Besser ist es tatsächlich, verschlüsselt zu arbeiten und ein zweites Credential mitzuführen (Extra-Cookie). Dann kann man, auch wenn eine Session zufällig|absichtlich getroffen wird, immer noch erkennen, dass etwas nicht stimmt. Da der Cookie in der Payload liegt, ist er vor dem Zugriff unterwegs sicher. Und die Wahrscheinlichkeit, dass man zeitnah auch den Cookie errät passend zum Session-Token ist tatsächlich sehr unwahrscheinlich, da der namensraum der Session alleine dem Affektierten User gehört, also keine Streudichte berücksichtigt werden muss.

          Bei https gehen wir eher von MITM-Angriffen aus, und da ist es egal wie du Tokens behandelst.

          1. Hello,

            Besser ist es tatsächlich, verschlüsselt zu arbeiten und ein zweites Credential mitzuführen (Extra-Cookie). Dann kann man, auch wenn eine Session zufällig|absichtlich getroffen wird, immer noch erkennen, dass etwas nicht stimmt. Da der Cookie in der Payload liegt, ist er vor dem Zugriff unterwegs sicher. Und die Wahrscheinlichkeit, dass man zeitnah auch den Cookie errät passend zum Session-Token ist tatsächlich sehr unwahrscheinlich, da der namensraum der Session alleine dem Affektierten User gehört, also keine Streudichte berücksichtigt werden muss.

            Bei https gehen wir eher von MITM-Angriffen aus, und da ist es egal wie du Tokens behandelst.

            Da bringst Du jetzt etwas durcheinander. Man kann per HTTPs eine Kommunikation betreiben. Die ist aber an beiden Enden wieder unverschlüsselt. Also kann ich mit brutaler Gewalt an meinem Ende Session-Tokens erfinden und schauen, was mir das andere Ende darauf antwortet.

            Ich habe solche Fälle von Treffern bei ein paar großen Portalen. Die waren total entsetzt, dass die diese Möglichkeit nicht berücksichtigt hatten. Einer der affektierten User konnte aber beweisen, dass er den Scheiß nicht verzapft haben konnte. Und da haben sie angefangen müssen, zu suchen.

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            1. hallo

              Ich habe solche Fälle von Treffern bei ein paar großen Portalen. Die waren total entsetzt, dass die diese Möglichkeit nicht berücksichtigt hatten. Einer der affektierten User konnte aber beweisen, dass er den Scheiß nicht verzapft haben konnte. Und da haben sie angefangen müssen, zu suchen.

              Ja aber hier haben wir es mit Kollisionsrisiken zu tun. Hashes sind nicht wirklich kollisionsresistent. Normalerweise verwendest du ja nicht nur ein sessiontoken sondern auch eine statische Information wie eine UserID, so dass zufällige Kollisionen ausgeschlossen werden können. Was dann bleibt ist der mutwillige Angriff nicht gegen den gesamten Pool offener Sessions, sondern gegen den sehr kleinen Pool offener Session-Tokens einer konkreten UserID.

              1. Hello,

                Ich habe solche Fälle von Treffern bei ein paar großen Portalen. Die waren total entsetzt, dass die diese Möglichkeit nicht berücksichtigt hatten. Einer der affektierten User konnte aber beweisen, dass er den Scheiß nicht verzapft haben konnte. Und da haben sie angefangen müssen, zu suchen.

                Ja aber hier haben wir es mit Kollisionsrisiken zu tun. Hashes sind nicht wirklich kollisionsresistent. Normalerweise verwendest du ja nicht nur ein sessiontoken sondern auch eine statische Information wie eine UserID, so dass zufällige Kollisionen ausgeschlossen werden können. Was dann bleibt ist der mutwillige Angriff nicht gegen den gesamten Pool offener Sessions, sondern gegen den sehr kleinen Pool offener Session-Tokens einer konkreten UserID.

                Nee, anders herum. Die User-ID steht üblicherweise in der Session. Und wenn ich z. B. einen Link aufrufe "/bilder.anzeigen" dann bekomme ich alle Bilder, die der Session-Inhaber sehen darf und vermutlich darf ich dann auch etwas dazu schreiben oder die Bilder löschen, oder andere dazu hochladen.

                Liebe Grüße
                Tom S.

                --
                Es gibt nichts Gutes, außer man tut es
        3. dem Affektierten User

          Immer wieder schön, wenn Leute ihr Deutsch mit "englischen" Begriffe garnieren, weil das ja so profimäßig aussieht – und sich damit restlos lächerlich machen.

          Affektiert: geziert, unnatürlich, affig, gschupft, etepetete, süßlich, theatralisch, hochgestochen, gekünstelt, gestelzt, manieriert, überkandidelt, geschraubt, gespreizt, hochmütig, künstlich

          The affected user = der betreffende Benutzer.

          Redet doch einfach normales Deutsch. Ist das so schwer?

          1. hallo

            Redet doch einfach normales Deutsch. Ist das so schwer?

            Wohl so schwer, wie die Forum-Tags hier zu bedienen...

          2. Föderalismus (kulturelle Kleinstaaterei) und unsinnige Rechtschreibreformen richten sich gegen das wichtigste Kulturgut der Deutschen Nation -- Die Deutsche Sprache. Das ist in einem Land, wo auf der ersten Umschlagseite des "Fachbuch für Deutsche Geschichte" die Gebrüder Grimm abgebildet sind, nichts Ungewöhnliches.

            Nurmalso nebenbei als Anmerkung zu Deiner Arroganz.

            MfG

  2. Hallo bobby,

    Ich verwende einen Mix aus Whirlpool sha512 und bcrypt.

    Du scheinst dir da etwas Eigenes gebastelt zu haben. Am besten (und einfachsten) nutzt du einfach die in PHP eingebauten Funktionen mit den Voreinstellungen, dann bist du auf der sicheren Seite.

    Gruß
    Julius

    --
    „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
    Andrew S. Tanenbaum (Quelle)
    1. Moin,

      "... Dies erstellt einen crypt()-kompatiblen Hash und benutzt die "$2y$"-Kennung... "

      Also nix anderes. Ich nutze halt crypt, aber noch kombiniert mit 2 anderen Verfahren. Also ist bcrypt noch hinreichend sicher. Danke

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Hallo bobby,

        Also nix anderes. Ich nutze halt crypt, aber noch kombiniert mit 2 anderen Verfahren. Also ist bcrypt noch hinreichend sicher.

        Im Moment vielleicht. Der Reiz an der API ist aber, dass die PHP-Voreinstellungen (sofern man also nicht explizit ein Verfahren angibt) mit einer neueren PHP-Version an den aktuellen Stand der Kryptographie (Runden, Hash-Algorithmus) angepastt werden können, ohne dass du etwas machen musst. Mittels password_needs_rehash() gibt es eine komfortable Möglichkeit, zu überprüfen, ob das bei der Erstellung eines bestimmten Hashs verwendete Verfahren noch aktuell ist und kann dann ggf. handeln, und das Passwort neu hashen.

        Warum etwas neu implementieren, das es bereits gibt und funktioniert?

        Gruß
        Julius

        --
        „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
        Andrew S. Tanenbaum (Quelle)
        1. Moin,

          OK. Ich muss zugeben, dass meine Funktion noch auf PHP 5.4 erstellt wurde. Da gabs password_hash noch nicht. Deswegen ja meine Frage ob es sicher ist. Dein "im Moment schon" genügt mir. Ich kann das, glaube ich, auch ganz leicht umstellen. Dein Einwurf, dass PHP automatisch die sicherste Methode in zukunft nimmt habe ich zur Kenntnis genommen und ich beziehe das grundsätzlich in meine Überlegungen mit ein. Danke

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          1. Hallo bobby,

            Ich muss zugeben, dass meine Funktion noch auf PHP 5.4 erstellt wurde.

            Dann ist dir sicher bewusst, dass 5.4 seit 1,5 Jahren keine Sicherheitsupdates mehr erhält. Es würde ebenfalls die Sicherheit erhöhen, auf eine neuere Version von PHP umzustellen, beispielsweise 7.1. Falls das dein Hoster nicht ermöglicht, würde ich den an deiner Stelle wechseln.

            Gruß
            Julius

            --
            „Unterschätze niemals die Datenübertragungsrate eines mit Bändern vollgeladenen Kombis, der über die Autobahn rast.“
            Andrew S. Tanenbaum (Quelle)
            1. Moin,

              Dann ist dir sicher bewusst, dass 5.4 seit 1,5 Jahren keine Sicherheitsupdates mehr erhält. Es würde ebenfalls die Sicherheit erhöhen, auf eine neuere Version von PHP umzustellen, beispielsweise 7.1. Falls das dein Hoster nicht ermöglicht, würde ich den an deiner Stelle wechseln.

              Mein System läuft auf 7.1.3 ... Diese Hash-Funktion ist eben noch aus alten Versionen mitgeschleift. Deswegen ja die Frage nach der Sicherheit 😉

              Gruß Bobby

              --
              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)