Felix Riesterer: http_auth-ähnliche PW-Prüfung

Liebes Forum,

heute möchte ich eine Userverwaltung in PHP so gestalten, dass die Passwörter der User in verschlüsselter (crypt()) Form online abgespeichert werden (keine DB á la mysql o.ä.!). Wenn jetzt ein User sich mit Benutzernamen und Passwort anmeldet, müsste mein Script prüfen, ob das eingegebene Passwort mit dem verschlüsselten Passwort zusammenpasst. Genauso, wie es der Apache-Webserver kann.

Wie kann ich in PHP diese Apache-like Prüfung vornehmen? Wenn ich das eingegebene PW mit crypt() verschlüssele, dann kommt jedesmal ein anderer String heraus (was ja auch so sein muss)...

Ich dachte auch schon an einen Umweg über http_auth, aber ich wüsste nicht, wie ich dynamisch für das Absenden des Formulars einen http_auth-Vorgang einrichten sollte. Das klingt ja schon an sich widersinnig!

Wer weiß Rat?

Liebe Grüße aus Ellwangen,

Felix Riesterer.

  1. hi,

    Wenn ich das eingegebene PW mit crypt() verschlüssele, dann kommt jedesmal ein anderer String heraus (was ja auch so sein muss)...

    Nimm das gleiche Salz, dann kommt auch das gleiche Ergebnis heraus, und du kannst es vergleichen.

    Ich dachte auch schon an einen Umweg über http_auth, aber ich wüsste nicht, wie ich dynamisch für das Absenden des Formulars einen http_auth-Vorgang einrichten sollte.

    Wenn die Authentifizierungsdaten für HTTP Auth über ein Formular eingegeben werden sollen, kann man das mit mod_auth_cookie "faken" - setzt aber dann natürlich zusätzlich noch Annahme von Cookies voraus.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Lieber wahsaga,

      Du bist verdammt schnell heute morgen! WOW!

      Nimm das gleiche Salz, dann kommt auch das gleiche Ergebnis heraus, und du kannst es vergleichen.

      Das bedeutet, dass ich nicht für jedes PW ein zufällig generiertes Salz nehmen darf? Hmm. Da war doch etwas mit den ersten beiden Zeichen eines verschlüsselten PW-Strings...

      Wenn die Authentifizierungsdaten für HTTP Auth über ein Formular eingegeben werden sollen, kann man das mit mod_auth_cookie "faken" - setzt aber dann natürlich zusätzlich noch Annahme von Cookies voraus.

      Ähm, ich glaube da liegt ein Missverständnis vor. Ich möchte lediglich erreichen, dass ein User-PW nicht im Klartext, sondern in einer verschlüsselten Form auf dem Webspace abgespeichert wird. Lediglich die rückwärtige Überprüfung (rein in meinem PHP-Script!) war mir von der Vorgehensweise her völlig unklar, denn PHP bietet keine decrypt-Funktion als Pendant zu crypt() an.

      Wenn ich Dich richtig verstanden habe, dann muss ich entweder ein einheitliches ("festes") Salz für alle PWs erstellen und verwenden, oder ich ermittle das zur Verschlüsselung jeweils zufällig generierte Salz anhand der ersten zwei Zeichen des abgelegten PW-Strings. Oder war da ein Missverständnis meinerseits?

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      1. Hallo Felix,

        denn PHP bietet keine decrypt-Funktion als Pendant zu crypt() an.

        Das _geht_ nicht. crypt() ist eine Hash-Funktion, d.h. sie ist nicht umkehrbar. Das ist ja gerade der Sinn dabei: Selbst wenn sich jemand irgendwie Zugang zu der Datei/Datenbank, wo die Passwörter gespeichert sind, verschafft, kann er das Passwort nicht (nur mit sehr sehr viel Aufwand) rauskriegen.

        Viele Grüße aus Freiburg,
        Marian

        --
        Microsoft broke Volkswagen's world record: Volkswagen made only 22 million bugs!
        <!--[if IE]><meta http-equiv="refresh" content="0; URL=http://www.getfirefox.com"><[endif]-->
  2. Hallo Felix,

    Du kannst crypt einen zweiten Parameter übergeben, der das Hashing beeinflusst (der Parameter wird "salt" genannt). Wenn Du ihn nicht angibst, erzeugt crypt einen zufälligen Parameter und arbeitet mit diesem. crypt() fügt den salt, den des verwendet, außerdem noch ganz an den Anfang des Ausgabestrings an. Du kannst das gespeicherte Passwort einfach als zweiten Parameter übergeben, crypt() wird sich davon nur den Teil raussuchen, den es für den salt braucht. D.h. if (crypt ($eingegebenes_klartextpassword, $gespeichertes_passwort) == $gespeichertes_passwort) { /* stimmt überein */ } else { /* stimmt nicht überein */ }

    Das ganze wird jedoch auch auf der crypt-Seite im Handbuch erklärt - inkl. Beispiel.

    Viele Grüße,
    Christian

    --
    "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." - Bjarne Stroustrup
    1. Lieber Christian,

      vielen Dank! Während ich wahsagas Posting beantwortet habe, konnte ich Deine Lösung noch nicht lesen, aber sie beantwortet meine Frage komplett.

      if (crypt ($eingegebenes_klartextpassword, $gespeichertes_passwort) == $gespeichertes_passwort) { /* stimmt überein */ } else { /* stimmt nicht überein */ }

      Das ist bestimmt die Lösung, die ich gesucht habe.

      Das ganze wird jedoch auch auf der crypt-Seite im Handbuch erklärt - inkl. Beispiel.

      Habe ich da etwas überlesen??? Mann mann mann, da sehe ich den Wald vor lauter Bäumen nicht mehr. Ts, ts, ts.

      Vielen Dank!

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

  3. echo $begrüßung;

    heute möchte ich eine Userverwaltung in PHP so gestalten, dass die Passwörter der User in verschlüsselter (crypt()) Form online abgespeichert werden (keine DB á la mysql o.ä.!).

    crypt() ist eine ziemlich alte Funktion. Wenn ihre Funktionalität nicht systemseitig durch einen verbesserten Algorithmus ersetzt worden ist, empfiehlt es sich, eine aktuellere Methode zu wählen, beispielsweise md5() [*] oder gleich sha1() [**].

    echo "$verabschiedung $name";

    [*] kann mittlerweile auch nicht mehr als sicher angesehen werden: http://de.wikipedia.org/wiki/MD5
    [**] Ich lese gerade, dass auch sha1 schon wieder "unsicher" geworden ist.

    1. Hallo dedlfix,

      [*] kann mittlerweile auch nicht mehr als sicher angesehen werden: http://de.wikipedia.org/wiki/MD5
      [**] Ich lese gerade, dass auch sha1 schon wieder "unsicher" geworden ist.

      Das heißt aber nur (steht iirc auch im Wikipedia-Artikel), dass man es nicht für verschlüsselte Übertragung nehmen soll, für die Speicherung von Passwörtern reicht es (normalerweise kommt ja eh niemand an die Hash-Werte dran)

      Viele Grüße aus Freiburg,
      Marian

      --
      Microsoft broke Volkswagen's world record: Volkswagen made only 22 million bugs!
      <!--[if IE]><meta http-equiv="refresh" content="0; URL=http://www.getfirefox.com"><[endif]-->
      1. echo $begrüßung;

        (normalerweise kommt ja eh niemand an die Hash-Werte dran)

        Normalerweise nimmt man es mit der Sicherheit eigener Scripte auch nicht so genau, denn normalerweise werden diese Lücken auch nicht ausgenutzt ...

        echo "$verabschiedung $name";

  4. Weitere Frage:

    Nachdem ich ein Passwort verschlüsselt habe, erhalte ich einen String mit diversen Zeichen. Da ich diese Zeichen "innerhalb von double quotes" ablegen möchte, muss ich natürlich sicherstellen, dass in diesem String keine solchen vorkommen.

    Kennt sich wer damit aus?

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    1. Moin!

      Da ich diese Zeichen "innerhalb von double quotes" ablegen möchte, muss ich natürlich sicherstellen, dass in diesem String keine solchen vorkommen.

      Also Escaping.

      Kennt sich wer damit aus?

      Addslashes oder die diversen Inkarnationen von $datenbank_escape_string()?

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
      1. Lieber Sven,

        danke für Deine Antwort.

        Addslashes oder die diversen Inkarnationen von $datenbank_escape_string()?

        Werde mir das nocheinmal zu Gemüte führen.

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

    2. echo $begrüßung;

      Nachdem ich ein Passwort verschlüsselt habe, erhalte ich einen String mit diversen Zeichen. Da ich diese Zeichen "innerhalb von double quotes" ablegen möchte, muss ich natürlich sicherstellen, dass in diesem String keine solchen vorkommen.

      Ein MD5-Hash besteht von Haus aus nur aus Ziffern und den Buchstaben a bis f.

      echo "$verabschiedung $name";