Andavos: Passwort verschlüsseln

Hallo,
ich habe vor 3 Tagen angefangen PHP zu lernen (mit ebook).

Meine Frage:

Ich möchte ein Login System bauen.
Man trägt sich auf einer Seite ein (Username + Passwort) und die Daten werden dann an diesen PHP Code gesendet:

<?
$user_name = array();

$passwort = md5($password);

$userdatei = fopen ("user.txt","r");
while (!feof($userdatei))
{
$zeile = fgets($userdatei,100);
$userdata = explode("|", $zeile);
array_push ($user_name,$userdata[0]);
}
fclose($userdatei);

if (in_array($username,$user_name))
{
echo "Username schon vorhanden";
}
else
{
$userdatei = fopen ("user.txt","a");
fwrite($userdatei, $username);
fwrite($userdatei, "|");
fwrite($userdatei, $passwort);
fwrite($userdatei, "\n");
fclose($userdatei);
echo "Ihre Anmeldung war erfolgreich!";
}
?>

In der user.txt wird das Passwort als als MD5 Code gespeichert.
Das sieht dann so aus:
Username|Passwort also z.B.:
b|92eb5ffee6ae2fec3ad71c777531578f

Wenn ich jetzt auf meine Login Seite gehe, und Username + Passwort eingebe, so sendet er die Daten an diesen Code:

<?

$password .= "\n";
$log=0;

$userdatei = fopen ("user.txt","r");
while (!feof($userdatei))
{
$zeile = fgets($userdatei,5000);
$userdata = explode("|", $zeile);
$passw = md5($userdata[1]);

if ($userdata[0]==$username and $passw==$password)
{
$log=1;
}
}
fclose($userdatei);

if ($log==1)
{
?>

Es geht

<?
}
else
{
echo "Du kommst hier net rein!";
}
?>

Der sagt aber immer "Falsche Passwort".
Wodran liegt das?

Wenn das Passwort nicht verschlüsselt gespeichert und abgefragt wird, dann sieht der Code so aus
<?
...
$userdatei = fopen ("user.txt","r");
while (!feof($userdatei))
{
$zeile = fgets($userdatei,5000);
$userdata = explode("|", $zeile);

if ($userdata[0]==$username and $userdata[1]==$password)
...
?>
Dann geht as Login System, bloß man muss nur die user.txt Datei aufrufen, und jeder sieht dann die Usernamen + Passwörter.

Kann mir bitte jemand sagen wie der Code richtig aussehen muss?
Ach ja, ich bin echt ein PHP Dau, also bitte nicht mir der Fachsprache anfangen.
Ich hab das Internet schon durchsucht, aber die meisten Texte hab ich nicht verstanden.

Über eine Antwort würde ich mich sehr freuen

Andavos

  1. $userdatei = fopen ("user.txt","r");
    while (!feof($userdatei))
    {
    $zeile = fgets($userdatei,5000);
    $userdata = explode("|", $zeile);
    $passw = md5($userdata[1]);
    if ($userdata[0]==$username and $passw==$password)

    Jetzt generierst du ja eine MD5-Summe aus der schon vorher generierten MD5-Summe, oder? Du mußt aber die MD5-Summe des eingegebenen Passwords mit der gespeicherten MD5-Summe vergleichen.

    $userdatei = fopen ("user.txt","r");
    while (!feof($userdatei)) {
    $zeile = fgets($userdatei,5000);
    $userdata = explode("|", $zeile);
    if ($userdata[0]==$username and $userdata[1]==md5($password)) { etc...

    Also, soweit ich den PHP-Code verstanden hab, bin selbst nicht sehr bewandert in PHP :)

    Gruß
    csx

    1. Wenn ich:
      $passw = md5($userdata[1]); rausnehme

      und das einsetzte:
      if ($userdata[0]==$username and $userdata[1]==md5($password))

      komm ich leider immer noch nicht rein

      1. $passw = md5($userdata[1]); rausnehme
        und das einsetzte:
        if ($userdata[0]==$username and $userdata[1]==md5($password))
        komm ich leider immer noch nicht rein

        Hi! Also, cih kann dir jetzt nicht dein Programm schreiben, aber dein Problem schien mir zu sein, daß du das gespeicherte Passwort 2 mal "verschlüsselst" (also, 2 mal daraus einen MD5-Hash erstellst), das Password, mit dem der Benutzer eintreten möchte aber überhaupt nicht.

        MD5 verschlüsselt das Passwort nicht, sonder generiert nur einen "Fingerabdruck". Ein mit MD5 "verschlüsseltes" Passwort kann nicht wieder "entschlüsselt" werden. ;)

        Gruß
        csx

        1. Hallo,
          ja das war auch ein Prob,
          hab ich ja auch behoben ;)

          Das MD5 nicht zurück geht, weiß ich, aber ich habe gelesen es sei Ideal es für PWs zu benutzten.

          Im neuen Script wird jetzt das Passwort rein Theo auch in MD5 umgewandelt. Geht aber leider immer noch nicht :(

  2. moin...

    überleg mal deine logik.

    du speicherst das passwort verschlüsselt, wenn du es dann vergleichst musst du die eingabe auch verschlüssel und erst dann kannst du den string vergleichen (da md5 nicht zurückkonvertiert werden kann)

    denke wenn du das beherzigst sollte es funktionieren.

    tschau

  3. Hallo Andavos,

    Man trägt sich auf einer Seite ein (Username + Passwort) und die Daten werden dann an diesen PHP Code gesendet:

    <?

    verwende besser '<?php', sonst bist du von short_open_tag=on abhängig

    $passwort = md5($password);

    wo kommt $password hier? übergibst du das in der url (bzw. per Formular mit method="post"?)? Wenn ja, musst du statt $password $_GET['password'] bzw. $_POST['password'] verwenden (bei dir ist vielleicht register_globals auf off (allerdings glaube ich das jetzt nicht, da das eintragen des Namens und des Passwortes ja funktioniert))

    (short_tag_open und register_globals sind Einstellungen in der php.ini (der Einstellungsdatei für php - wie die bei dir stehen kannst du mit phpinfo() feststellen)

    if (in_array($username,$user_name))

    da hast du ja eine Funktion entdeckt, die ich erst vor kurzem kennengelernt habe :-)

    fwrite($userdatei, $username);
    fwrite($userdatei, "|");
    fwrite($userdatei, $passwort);
    fwrite($userdatei, "\n");

    warum fasst du das nicht alles zu einem String zusammen und schreibst es dann in die Datei?

    $password .= "\n";

    für was ist das?

    $userdata = explode("|", $zeile);
    $passw = md5($userdata[1]);

    hier verschlüsselst du das gespeicherte Passwort nochmal - das dürfte nicht das sein, was du willst.

    if ($userdata[0]==$username and $passw==$password)

    statt $passw==$password wäre vermutlich ein md5($_POST['password'])==trim($userdatea[1]) sinnvoller (sofern du das Passwort per post in einem Formularfeld mit dem namen password an die Datei übergibst). Mit trim() entfernst du den Zeilenumbruch hinter dem verschlüsselten Passwort (->http://de2.php.net/trim).

    }
    }

    du solltest dir angewöhnen, deinen Quelltext einzurücken - dann bleibt er lesbarer.

    if ($log==1){ ?>

    was passiert, wenn auf die Datei auf die die Loginseite verweist mit ?log=1 aufrufst? wenn du "Es geht" hast du ein Sicherheitsloch (register_globals auf off stellen hilft hier)

    Dann geht as Login System, bloß man muss nur die user.txt Datei aufrufen, und jeder sieht dann die Usernamen + Passwörter.

    dann setzte die Rechte der datei user.txt so, dass sie nicht von jedem aufgerufen werden kann (was aber u.U. nicht gehen wird) alternativ kannst du auch ein ".ht" vor den Dateinamen setzten - dann wird die Datei nicht ausgeliefert (wenn das ganze auf einem Apache läuft)

    also bitte nicht mir der Fachsprache anfangen.

    ich habe mich bemüht :-)

    Ich hab das Internet schon durchsucht,

    das _ganze_? :-)

    Grüße aus Nürnberg
    Tobias

    --
    Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
    1. Hallo,
      also ich lass das per Apache laufen (hab ja keinen PHP Server :( ).
      da geht das mit
      <?

      Das $password kommt aus dem Formular "Name=password".
      Ich hab das zwar mit _Post... gelesen, aber so geht das bei mir auch.

      Also er schreibt die sachen in eine Datei: Username|Passwort

      $password .= "\n";
      für was ist das?

      ka ^^, hab den Code teilweise kopiert.
      Aber ich glaube das er die Sache dann so speichert:
      Username|Passwort <br>
      Username|Passwort <br>

      da <br> sieht man dann aber nicht ;)
      Also wenn ich die datei aufrufe steht da:

      Andavos|andavos
      Anda|vos

      Das sicherheits loch ist nicht weiter wichtig ;)
      Dennoch danke für den tipp.

      1. Hallo Andavos,

        also ich lass das per Apache laufen (hab ja keinen PHP Server :( ).

        hab ich was von einem PHP-Server geschrieben? den gibt es afaik nämlich nicht - php läuft immer als "Erweiterung" eines Apachen (oder auch IIS o.ä.)

        da geht das mit
        <?

        wenn es bei dir geht, heißt es noch lange nicht, dass es überall geht.

        Das $password kommt aus dem Formular "Name=password".
        Ich hab das zwar mit _Post... gelesen, aber so geht das bei mir auch.

        definiere "geht nicht". (im übrigen musst du "POST" groß schreiben, also: $_POST['password'])

        $password .= "\n";
        für was ist das?
        ka ^^, hab den Code teilweise kopiert.

        ist der Code nicht erklärt?

        da <br> sieht man dann aber nicht ;)
        Also wenn ich die datei aufrufe steht da:
        Andavos|andavos
        Anda|vos

        ja, "\n" ist ein Zeilenumbruch - nur ist es recht sinnlos, den an $password dranzuhängen (zumal $password zum Vergleichen ja noch verschlüsselt werden muss) - ich würde den Zeilenumbruch (wie geschrieben) mit trim() am gespeicherten Passwort ändern.

        Das sicherheits loch ist nicht weiter wichtig ;)

        es ist dein Sicherheitsloch... imho sollte das nicht egal sein.

        Grüße aus Nürnberg
        Tobias

        --
        Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
        1. Hallo,
          ne das gibts kein Sicherheitsloch.

          _POST hab ich im Script groß geschrieben, geht dennoch nicht.

          Der Login Script sieht jetzt so aus:

          <?
          $log=0;
          $userdatei = fopen ("user.txt","r");
          while (!feof($userdatei))
          {
          $zeile = fgets($userdatei,5000);
          $userdata = explode("|", $zeile);
          if ($userdata[0]==$username and md5($HTTP_POST_VARS["password"])==$userdata[1])
          {
          $log=1;
          }
          }
          fclose($userdatei);
          if ($log==1)
          {
          ?>
          Es geht
          <?
          }
          else
          {
          echo "Du kommst hier net rein!";
          }
          ?>

          Hör mir auf mit dem Script den ich runtergeladen habe.....

          Da waren tausend Fehler drin.
          Der hat vorne und hinten nicht funktioniert.

          Ich habe mir die wichtigsten Sachen aus dem Script rauskopiert und evt. geändert.

          1. Hallo Andavos,

            ne das gibts kein Sicherheitsloch.

            ja, weil du am anfang $log=0 schreibst - ich würde register_globals trotzdem auf off stellen...

            _POST hab ich im Script groß geschrieben,

            welche php-Version hast du denn? (unten verwendest du nämlich $HTTP_POST_VARS[...])

            geht dennoch nicht.

            das ist keine Fehlerbeschreiben. Was funktioniert nicht? Fehlermeldung? Verhalten soll/ist?

            if ($userdata[0]==$username and md5($HTTP_POST_VARS["password"])==$userdata[1])

            warum verwendest du nicht trim($userdata[1]) wie ich es dir geraten habe?

            btw: das Einrücken solltest du noch etwas üben (wenn du wissen willst, wie - schau ins Archiv)

            Grüße aus Nürnberg
            Tobias

            --
            Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
            1. Hallo,
              PHP 4.0.5 benutze ich.
              Ja das mit _POST geht nicht, aber das mit HTTP_POST... geht

              Was ich mit geht dennoch nicht meine:
              Es spuckt dann immer echo "Du kommst hier nicht rein" aus, also waren die Passwörter nicht identisch.

              Auch das mit trim() geht leider nicht :(

              1. Hallo,
                ich benutzte einmal eintragen.php um die Daten in user.txt zu speichern, und login.php um die Daten abzufragen.

                Kann es daran liegen?
                Dass der MB5 in login.php anders ist als in eintragen.php?

              2. Hallo Andavos,

                PHP 4.0.5 benutze ich.

                *argh* du solltest dringend updaten.

                Ja das mit _POST geht nicht, aber das mit HTTP_POST... geht

                kein Wunder - das Array $_POST gibt es erste seit Version 4.1 (das du allerdings eine soo alte Version hast, konnte ich nicht ahnen) - die Version 4.1 ist immerhin von 12/2001...

                Es spuckt dann immer echo "Du kommst hier nicht rein" aus, also waren die Passwörter nicht identisch.

                hast du versucht dir mal die 4 Variablen die du in deiner if-Klammer stehen hast auszugeben, was da eigentlich drinsteht? Im Übrigen solltest du immer alles ausgeben, um zu testen, was da eigentich drinsteht.

                du könntest auch mal versuchen mit file() zu arbeiten - das gibt dir gleich einen Array zurück, bei dem jedes Element eine Zeile der Datei ist.

                Grüße aus Nürnberg
                Tobias

                --
                Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
                1. Hallo,
                  freu es geht.
                  Aber bitte nicht fragen wodran das liegt ^^
                  Denn ich hab keine Ahnung.

                  Die neuste Version saug ich mir gerade ;)

                  hier der Code der geht:

                  <?
                  $log=0;
                  $userdatei = fopen ("user.txt","r");
                  while (!feof($userdatei))
                  {
                  $zeile = fgets($userdatei,5000);
                  $userdata = explode("|", $zeile);
                  if ($userdata[0]==$username and md5($HTTP_POST_VARS["password"])==trim($userdata[1]))
                  {
                  $log=1;
                  }
                  }
                  fclose($userdatei);
                  if ($log==1)
                  {
                  ?>
                  Es geht
                  <?
                  }
                  else
                  {
                  echo "Ne";
                  }
                  ?>

                  Freu.

                  Viel vielen Dank für eure Hilfe

                  1. Hallo Andavos,

                    Aber bitte nicht fragen wodran das liegt ^^

                    *grmpf* an trim() lag es:

                    if ($userdata[0]==$username and md5($HTTP_POST_VARS["password"])==trim($userdata[1]))

                    in dieser Zeile ist die einzige Änderung gegenüber der Version in [pref:t=54404&m=302278]: trim($userdata[1]) statt $userdata[1]

                    Grüße aus Nürnberg
                    Tobias

                    --
                    Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
    2. Hi Tobias!

      if ($log==1){ ?>
      was passiert, wenn auf die Datei auf die die Loginseite verweist mit ?log=1 aufrufst? wenn du "Es geht" hast du ein Sicherheitsloch (register_globals auf off stellen hilft hier)

      Wow! Da hatte ich noch gar nicht dran gedacht! Ich bin auch recht neu bei PHP und es ist ja eigentlich ganz lustig, das alles so automatisch geht (kennt man gar nicht von Perl, vor allem ich als Module-Muffel ;) Aber jetzt bemerke ich grade, daß diese ganze Automatik ja wohl auch nicht gerade ungefährlich ist. Danke dir für den Tipp!

      Gruß
      csx