MB: passord_verify() hash

moin,

ich möchte gern im groben wissen, wie password_verify() in PHP funktioniert. Ich weis das der Hashwert der aus der Funktion password_hash() generiert wurde jedes mal ein anderer ist. Spielen microtime() usw. eine Rolle??? Sonst wüsste ich es mir nicht zu erklären.

lgmb

  1. Nein. Es wird ein salt gebildet. Also "ausreichender Zufall". Wobei die Zeit bei der Ermittlung des "Zufalls" neben vielen anderen Items eine Rolle spielt.

    Literatur.

  2. Hallo

    ich möchte gern im groben wissen, wie password_verify() in PHP funktioniert. Ich weis das der Hashwert der aus der Funktion password_hash() generiert wurde jedes mal ein anderer ist. Spielen microtime() usw. eine Rolle??? Sonst wüsste ich es mir nicht zu erklären.

    Wie Regina bereits erklärte, wird mit einem Salt gearbeitet. Der Salt wird entweder vorgegeben oder automatisch generiert. Weiterhin können der zu verwendende Algorithmus und die Anzahl der Durchläufe angegeben oder die Vorgabewerte der Funktion genutzt werden.

    Alle diese Werte (Salt, Algorithmus, Zahl der Durchläufe) sind hernach auch Bestandteile des Hashes des Passworts. Damit ist es möglich, den Vergleich mit der Funktion password_verify durchzuführen, da diese alle benötigten Informationen aus dem Hash, mit dem eine Passworteingabe verglichen werden soll, extrahieren kann. Die Passworteingabe wird, mit den selben Parametern wie der vorhandene Hash ebenfalls gehasht. Jenachdem, wie der Vergleich ausfällt, kommt dann true oder false heraus.

    Tschö, Auge

    --
    Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
    Kleine freie Männer von Terry Pratchett
    1. moin,

      zu PASSWORD_DEFAULT habe ich selbst cost und salt manuell angegeben z.B.:

      $hash = password_hash( 'foo', PASSWORD_DEFAULT, [ 'salt' => 'bar', 'cost' => '8' ] );
      

      irgendwie krig ich es mit password_verify() nich hin, die beiden zu vergleichen. bestimmt n dummer flüchtigkeitsfehler von mir selbst 😕

      lgmb

      1. Hallo

        zu PASSWORD_DEFAULT habe ich selbst cost und salt manuell angegeben z.B.:

        $hash = password_hash( 'foo', PASSWORD_DEFAULT, [ 'salt' => 'bar', 'cost' => '8' ] );
        

        irgendwie krig ich es mit password_verify() nich hin, die beiden zu vergleichen. bestimmt n dummer flüchtigkeitsfehler von mir selbst 😕

        Ich kann das Problem nachstellen. Lasse ich das Array-Element für den Salt weg, funktioniert die Passworterstellung, mit deinem Array gibt password_hash nur NULL zurück, was bedeutet, dass die Funktion grundsätzlich läuft. Der Default-Hashing-Algorithmus von PHP (aktuell Blowfish (BCrypt)) erlaubt einen händisch angegebenen Salt. Mit PHP7 ist das zwar deprecated, aber immer noch nicht verboten. Mein Hauptproblem an diesem Punkt: Ich sehe keinerlei Fehlermeldungen.

        Setze ich für error_reporting den Wert E_ALL, wird auch der Grund für die fehlerhafte Erstellung des Hashes sichtbar. Der Salt ist um Längen zu kurz.

        Warning: password_hash(): Provided salt is too short: 3 expecting 22 in /home/pi/Web/sms/client-calls/testing.php on line 7
        

        Mit einem längeren Salt funktioniert der Aufruf. Das Handbuch empfiehlt, den Salt von System erstellen zu lassen. Wenn die händische Vorgabe eines Salt mit PHP7 sowieso missbilligt wurde, ist damit zu rechnen, dass diese Möglichkeit mittelfristig rausfliegt. Da ist es besser, den gleich wegzulassen und zudem einen höheren Wert für cost zu benutzen. Der Vorgabewert von PHP ist 10, mit 8 bleibst du sogar darunter. Nicht gut.

        Mit dem folgenden Code kannst du das Problem nachvollziehen.

        <?php
        
        ini_set('display_errors', 1);
        error_reporting(E_ALL);
        
        $password = 'foo';
        // salt ist 3 Zeichen lang, Aufruf funktioniert nicht
        #$hash = password_hash($password, PASSWORD_DEFAULT, ['salt' => 'bar', 'cost' => '8']);
        // salt auto, Aufruf funktioniert
        #$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => '12']);
        // cost auto, salt auto, Aufruf funktioniert
        #$hash = password_hash($password, PASSWORD_DEFAULT);
        // cost ist auf 8 festgelegt, salt ist 24 Zeichen lang, Aufruf funktioniert
        $hash = password_hash($password, PASSWORD_DEFAULT, ['salt' => 'barristaschießmichtot!!!', 'cost' => '8']);
        
        $check = password_verify($password, $hash);
        
        echo '<h2>Inhalt <code>$password</code></h2>';
        var_dump($password);
        echo '<h2>Inhalt <code>$hash</code></h2>';
        var_dump($hash);
        echo '<h2>Inhalt <code>$check</code></h2>';
        var_dump($check);
        
        ?>
        

        Tschö, Auge

        --
        Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
        Kleine freie Männer von Terry Pratchett
        1. moin,

          danke für die ausfürliche AW. Ich werde mich damit befassen.

          lg

      2. moin,

        zu PASSWORD_DEFAULT habe ich selbst cost und salt manuell angegeben z.B.:

        Das ist keine gute Idee!

        password_hash() kann mit dem nächsten PHP-Update andere Algos und eventuell Vorschriften benutzen, die dann einen Salt größerer Länge und/oder mehr Runden (costs) verlangen. Die Funktion wird das selbständig richtig und besser ermitteln als Du zu Fuß oder willkürlich.

        password_hash() dokumentiert die verwendeten Algos und Vorschriften zwischen den ersten $-Symbolen. Man kann danach suchen.

        1. moin,

          zu PASSWORD_DEFAULT habe ich selbst cost und salt manuell angegeben z.B.:

          Das ist keine gute Idee!

          hat mir @@Auge zuvor erklärt.

          password_hash() dokumentiert die verwendeten Algos und Vorschriften zwischen den ersten $-Symbolen. Man kann danach suchen.

          Du greifst die Frage bezüglich Algos + Dokumentation schon vorweg. Also, ich Danke.

          lgmb

  3. moin,

    Gelöst: Ich hab bei password_verify() zwei Hashs mit eimnander verglichen und nich ein string mit dazugehörigem Hash. Sorry.

    lgmb