IT-Academy Logo
Sign Up Login Help
Home - Programmieren - PHP - PHP: Passwörter als Grafik anzeigen



PHP: Passwörter als Grafik anzeigen

So genannte Spamcomputer registrieren sich hunderte Male bei Webseiten, die dadurch sehr belastet werden. Dieser Artikel möchte zeigen wie man bei der Registrierung ein kleine Grafik generiert worauf das Passwort steht, dass der neue Benutzer erst eingeben muss. So wird sichergestellt, dass es sich um einen menschlichen Benutzer handelt.


Autor: Patrick Faes (dreamer)
Datum: 10-10-2004, 12:09:36
Referenzen: siehe Text
Schwierigkeit: Fortgeschrittene
Ansichten: 10985x
Rating: 9 (2x bewertet)

Hinweis:

Für den hier dargestellte Inhalt ist nicht der Betreiber der Plattform, sondern der jeweilige Autor verantwortlich.
Falls Sie Missbrauch vermuten, bitten wir Sie, uns unter missbrauch@it-academy.cc zu kontaktieren.

[Druckansicht] [Als E-Mail senden] [Kommentar verfassen]



Einführung

Auf viele Webseiten kann man sich registrieren lassen um z.B. einen wöchtenlichen Newsletter zu erhalten, an einem Forum teil zu nehmen, Zutritt zu bestimmte Inhalte zu erhalten usw.

Nach der Registrierung erhält man einen Benutzernamen und ein Passwort. Jedoch melden sich oft auch Spamcomputer an, die sich hunderte Male registrieren und so Webseiten extrem belasten.

Eine Methode um sich dagegen zu schützen, besteht darin ein Passwort zu generieren und zu fragen diese ein zu tippen. Allerdings wird das Passwort also im Quellcode mitgegeben, wodurch Spamcomputer diese auslesen können und das Formular auch selbständig ausfüllen können.

Computer können allerdings keine Texte auf Grafiken lesen. Man kann natürlich keine hunderte von Grafiken bauen. Deshalb kan man sie auch von PHP generieren lassen. Einige Beispiele wie diese aussehen können:



Jeder der sich registrieren möchte, muss die Zeichenkombination die auf der Grafik steht im Formular eintippen und abschicken. Nur wenn dies richtig gemacht wurde, wird der Account freigschaltet.

Dieser Artikel möchte zeigen wie so ein System erstellt wird. Dafür wird Gebrauch gemacht von einfachen Grafiken, nichts kompliziertes. Auch möchte dieser Artikel nicht ein Loginsystem1 an sich zeigen. Sehen Sie dafür unten in den Referenzen nach.

Die theoretische Wirkung

Anfangs starten wir eine Session. Während einer Session werden bestimmte Werte durch den Server gespeichert. So kann das Passwort auf der zweiten Seite kontrolliert werden.
Danach werden beliebige Zeichen aus einer vorgegebenen Gruppe von Zeichen genommen und diese bilden dann das Passwort.
Mittels PHP wird dann eine kleine Grafik generiert, die mit dem Passwort beschriftet wird.
Danach wird ein Formular erstellt, dass der Benutzer ausfüllen soll.
In einem zweiten Script wird dann kontrolliert ob die Passwörter übereinstimmen.

Die Praxis

Am Anfang des Script starten wir die Session2.
<?php
session_start();
?>
Als nächstes wollen wir ein Passwort per Zufall generieren und diese speichern.
<?php
$zeichen = array('a','b','c','d','e',1,2,3,4,5);
$passwort_laenge = rand(4,7);

if ( !isset($_SESSION["passwort"]) );
  {
   for ($i = 0; $i < $passwort_laenge; $i++)
     {
     $hinzufuegen = array_rand($zeichen, 1);
     $_SESSION["passwort"] .= $zeichen[$hinzufuegen];
     }
  }?>
Zuerste erstellen wir ein Array3 mit dem Namen $zeichen. Darin schreiben wir dann die verschiedenen Buchstaben und Ziffern die zur Generierung des Passwortes verwendet werden können. Diese können theoretisch auch Lesezeichen (wie z.B. Ampersands [&], Anführungszeichen ["] usw.) sein, jedoch müssten diese dann "escaped"4 werden, da diese in PHP interpretationsgefühlige Zeichen sind. Das geht mit die Funktionen addslashes()5 und stripslashes()6 (es könnte sein, dass der Server so konfiguriert ist, dass dieser das von selbst macht, das können Sie mit der Funktion get_magic_quotes_gpc()7 testen). Jedoch werden diese hier nicht verwendet. Im obigen Beispiel wurden einzelne Buchstaben bzw. Ziffer verwendet. Sie können allerdings auch Kombinationen von mehreren Buchstaben und Ziffern verwenden. Beachten Sie auch, dass PHP einen Unterschied macht zwischen Groß- und Kleinschreibung8 (aBc <> AbC).

Mit der Funktion rand()9 speichern wir eine Zufallszahl in der Variable $passwort_laenge. Im obigen Beispiel ist das eine von 4 bis zu 7 Zeichen lange.

Wenn die Sessionvariable10 $_SESSION["passwort"] noch nicht gesetzt wurde, wird ein Passwort generiert (geschieht mit einer IF-Abfrage11). Ich erzähle später warum wir das erst testen. In einer For-Schleife12 speichern wir soviele Zeichen im Passwort wie die Länge angibt.
Mit der Funktion array_rand()13 wird per Zufall der Key14 eines Zeichen aus dem Array $zeichen genommen und in der Variable $hinzufuegen gespeichert.
Damit können wir jetzt ein Zeichen aus dem Array nehmen und am Passwort hinzufügen.

Da wir jetzt wissen wie lang das Passwort ist, können wir auch bestimmen wie groß die Grafik sein soll.
<?php
$font = 4;
$breite = imagefontwidth($font) * strlen($_SESSION["passwort"]) + 4;
$hoehe = imagefontheight($font) + 4;
$bild = imagecreate($breite, $hoehe) or die("Fehlermeldung");
?>
In der Variable $font speichern wir die Schriftgröße womit die Grafik später belegt wird. PHP akzeptiert dazu eine Zahl von 1 (klein) bis 5 (groß), aber dazu später mehr.
Wir errechnen mit der Funktion imagefontwidth()15 (an hand von $font) die Breite der Grafik. Der Platz (in Bildpunkte) die ein Buchstabe braucht, multipliziert mit der Zeichenlänge des Passwortes (gemessen mit der Funktion strlen()16) plus 4 ist die Grafikbreite in Pixel. Die 4 extra Bildpunkte brauchen wir weil die Buchstaben links und rechts 2 Bildpunkte Abstand zum Grafikrand haben sollen.
Das gleiche machen wir mit der Höhe (mit der Funktion imagefontheight()17).
Da wir jetzt die Höhe und Breite der Grafik haben, können wir mit der Funktion imagecreate()18 die Umrisse der Grafik erstellen.

Anmerkung: Sie können die Grafik auch erstellen an hand von einer anderen Grafik mit der Funktion imagecreatefrompng()19. Dafür wird eine PNG-Grafik20 gebraucht. In dieses Tutorial werden auch PNG-Grafiken erstellt. PHP kann auch Grafiken in andere Formate erstellen, wie z.B. GIF und JPEG. Aber dazu später mehr.

Als nächstes bestimmen wir die Farben für den Hintergrund und die Buchstaben. Das muss unbedingt in dieser Reihenfolge sein.
<?php
$hintergrundfarbe = '85,107,47|139,139,122|255,222,173';
$hintergrundfarbe = explode('|',$hintergrundfarbe);
shuffle($hintergrundfarbe);
$hintergrundfarbe = explode(',' , $hintergrundfarbe[0]);
$hintergrundfarbe = imagecolorallocate($bild, $hintergrundfarbe[0],
		    $hintergrundfarbe[1], $hintergrundfarbe[2]);

$textfarbe = '47,79,79|119,136,153|0,0,128';
$textfarbe = explode('|',$textfarbe);
shuffle($textfarbe);
$textfarbe = explode(',' , $textfarbe[0]);
$textfarbe = imagecolorallocate($bild, $textfarbe[0], $textfarbe[1], $textfarbe[2]);
?>
Die Methode ist bei jeder Farbe gleich. Die Hintergrundfarbe wird gespeichert in $hintergrundfarbe und die Textfarbe in $textfarbe.
PHP braucht für die Generierung der Grafik Farben im RGB-Notation21 (schauen Sie unten in den Referenzen nach für eine Tabelle mit RGB-Werten). Die Farben können auch per Zufall gewählt werden. Dafür brauchen wir wieder einen Zufallsgenerator. Die Notation sieht so aus:

Rot-Wert , Grün-Wert , Blau-Wert

Beachten Sie dabei die Kommas. Die verschiedenen Farben werden getrennt durch einem vertikalen Strich ( | ). Mit der Funktion explode()22 werden die verschiedenen Farben getrennt und mit der Funktion shuffle()23 wird die Reihenfolge der Farben (die durch explode() in einem Array gespeichert wurden) geändert. Wir nehmen die erste Farbe und trennen die RGB-Werte mit der Funktion explode(). Mit der Funktion imagecolorallocate24 wird die Grafik eine Farbe zugewiesen.
Die Funktion braucht dazu vier Parameter: die Umrisse der Grafik (gespeichert in der Variable $bild) und die drei RGB-Werte.

Die Grafik muss jetzt auf dem Server gespeichert werden, sodass sie später auch geladen werden kann (wenn man nur die Grafik am Benutzer sendet, braucht man dies nicht, aber dann kann man kein HTML mehr senden, und das ist nicht der Sinn der Sache). Die Grafik soll auch ein Zufallsname haben.
<?php
$grafik_name;
$zeichen2 = array('o','zfd','pog','1g7');
$laenge = rand(3,5);
for ($i = 0; $i < $laenge; $i++)
   {
   $hinzufuegen = array_rand($zeichen2, 1);
   $grafik_name .= $zeichen[$hinzufuegen];
   }

imagestring($bild, $font, 2, 2, $_SESSION["passwort"], $textfarbe);
$grafik_name = 'zzzz'.$grafik_name.'.png';
imagepng($bild,$grafik_name);
imagedestroy($bild);
?>
Wir deklarieren erst die Variable $grafik_name worin wir später der Name der Variable speichern. Der Name wird wieder durch einem Zufallsgenerator zusammen gestellt. Dafür brauchen wir ein neues Array mit Zeichen (hierin dürfen absolut keine Lesezeichen vorkommen). Ansonsten geht das weiter wie wir oben schon das Passwort generiert haben.

Mit der Funktion imagestring()25 fügen wir der Grafik das Passwort hinzu. Die Funktion braucht 6 Parameter:
  1. die Umrisse der Grafik (gespeichert in $bild)
  2. die Schriftgröße (gespeichert in $font)
  3. der Abstand des Textes zum linken Rand (X-Achse)
  4. der Abstand des Textes zum unterem Rand (Y-Achse)
  5. der Text (gespeichert in $_SESSION["passwort"])
  6. die Farbe des Textes (gespeichert in $textfarbe)
Nachdem die Grafiken einmal benutzt sind, werden sie nicht weiter gebraucht. Es ist zu bevorzugen diese in einem separaten Verzeichnis zu speichern. Manche Hosts verhindern es, dass PHP selbst Dateien in einem anderen Verzeichnis schreibt. Man kann daher den Namen anfangen lassen mit viermal den Buchstaben z. Da die Dateien auf dem Server alfabetisch geordnet sind, werden diese Grafiken immer unten stehen und können deshalb leicht gelöscht werden.
Natürlich muss am Ende noch die Datei-Endung am Name der Grafik hinzugefügt werden. In diesem Fall ist das die Endung .png, weil wir hier eine PNG-Grafik erstellt haben. Mit der Funktion imagepng()26 wird die Grafik auf dem Server gespeichert. Nachdem das geschehen ist, kann mit imagedestroy()27 den Speicher freigegeben werden.
<?php
echo '<img src="'.$grafik_name.'"><br>
<form action="kontrolle.php" method="post">
<input type="text" size="'.$passwort_laenge.'" name="passwort"><br>
<input type="submit">
</form>';
?>
Als letztes brauchen wir noch ein Formular28, dass der Benutzer ausfüllen muss. Die Grafik wird auch angezeigt (der Source der Grafik ist gespeichert in $grafik_name). Das Formular übergibt das Passwort.

Danach brauchen wir noch ein zweites Script, dass die Eingabe kotrolliert.
<?php
session_start();

if ($_POST["passwort"] != $_SESSION["passwort"])
   {
     header("location:registrierung.php");
   }
else
   {

   }
?>
Wenn das eingegebene Passwort nicht übereinstimmt mit dem Passwort das auf dem Server gespeichert ist, wird der Benutzer mit der Funktion header()29 zurück zur vorherigen Seite geschickt. Da das Passwort noch gespeichert ist, kann es wieder benutzt werden. Daher haben wir die Passwortgenerierung auch abhängig davon gemacht ob das Passwort schon generiert wurde.
Code einbauen

Der Code ist recht einfach ein zu bauen. Beachten Sie allerdings, dass Sie auch ein richtiges Registrierungsscript brauchen. Danach kommt dieses Script und danach noch die Kontrolle die Sie gerade gesehen haben.

Auch müssen Sie die Arrays $zeichen und $zeichen2 nach Wunsch ändern. Diese dienen dazu die Passwörter und die Grafiknamen zu generieren. Vermeiden Sie den Gebrauch von interpretationsgefühlige Zeichen wie Striche, Anführungszeichen, Schrägstriche, Ampersands usw.

In diesem Tutorial wurde gebrauch gemacht von Grafiken im PNG-Format. Dieses Format ist kompatibel mit den meisten Browsern. Wenn Sie lieber GIF oder JPEG als Format verwenden, müssen Sie überal im Script PNG durch GIF bzw. JPEG (z.B. die Funktion imagegif()) ersetzen.
<?php
session_start();

$zeichen = array('a','b','c','d','e',1,2,3,4,5);
$passwort_laenge = rand(4,7);

if ( !isset($_SESSION["passwort"]) );
  {
   for ($i = 0; $i < $passwort_laenge; $i++)
     {
     $hinzufuegen = array_rand($zeichen, 1);
     $_SESSION["passwort"] .= $zeichen[$hinzufuegen];
     }
  }

$font = 4;
$breite = imagefontwidth($font) * strlen($_SESSION["passwort"]) + 4;
$hoehe = imagefontheight($font) + 4;
$bild = imagecreate($breite, $hoehe) or die("Fehlermeldung");

$hintergrundfarbe = '85,107,47|139,139,122|255,222,173';
$hintergrundfarbe = explode('|',$hintergrundfarbe);
shuffle($hintergrundfarbe);
$hintergrundfarbe = explode(',' , $hintergrundfarbe[0]);
$hintergrundfarbe = imagecolorallocate($bild, $hintergrundfarbe[0],
		    $hintergrundfarbe[1], $hintergrundfarbe[2]);

$textfarbe = '47,79,79|119,136,153|0,0,128';
$textfarbe = explode('|',$textfarbe);
shuffle($textfarbe);
$textfarbe = explode(',' , $textfarbe[0]);
$textfarbe = imagecolorallocate($bild, $textfarbe[0], $textfarbe[1],
	     $textfarbe[2]);

$grafik_name;
$zeichen = array('o','zfd','pog','1g7');
$laenge = rand(3,5);
for ($i = 0; $i < $laenge; $i++)
   {
   $hinzufuegen = array_rand($zeichen2, 1);
   $grafik_name .= $zeichen[$hinzufuegen];
   }

imagestring($bild, 3, 5, 5, $_SESSION["passwort"], $textfarbe);
$speichern = 'zzzz'.$grafik.'.png';
imagepng($bild,$speichern);
imagedestroy($bild);

echo '<img src="'.$speichern.'"><br>
<form action="" method="post">
<input type="text" size="'.$passwort_laenge.'" name="test"><br>
<input type="hidden" name="session" value="'.session_id().'">
<input type="submit">
</form>';?>
?>

Referenzen
  1. Mit PHP können Sie komplette Loginsysteme bauen: mehr dazu
  2. Während einer Session werden bestimmte Werte zeitlich auf dem Server gespeichert: mehr dazu
  3. Arrays sind Ketten von Variable Werte: mehr dazu
  4. Interpretationsgefühlige Zeichen müssen in PHP escaped werden: mehr dazu
  5. Die Funktion addslashes() escaped automatisch: mehr dazu
  6. Die Funktion stripslashes() macht das umgekehrte von der Funktion addslashes(): mehr dazu
  7. Die Funktion get_magic_quotes_gpc() zeigt die aktuelle Konfiguration des Servers im Bezug zum Escapen: mehr dazu
  8. In PHP müssen Groß- und Kleinbschreibung beachtet werden: mehr dazu
  9. Die Funktion rand() wählt eine Zufallszahl: mehr dazu
  10. Sessionvariable: mehr dazu
  11. Mit dem IF-Konstrukt werden bestimmte Anweisungen nur ausgeführt wenn eine Bedingung wahr ist: mehr dazu
  12. Eine FOR-Schleife wiederholt eine Anweisung einige Male: mehr dazu
  13. Die Funktion array_rand() wählt per Zufall einen Key aus einem Array: mehr dazu
  14. Arrays bestehen aus Keys (Schlüssel) und Values (Werte): mehr dazu
  15. Imagefontwidth() gibt die Zeichenbreite des angegebenen Fonts in Pixeln zurück: mehr dazu
  16. Strlen() ermittelt die Länge einer Zeichenkette: mehr dazu
  17. Imagefontheight() gibt die Zeichenhöhe des angegebenen Fonts in Pixeln zurück: mehr dazu
  18. ImageCreate() gibt den Zeiger auf ein neues Bild zurück: mehr dazu
  19. Erzeugt ein neues Bild im PNG-Format, welches aus einer Datei oder von einer URL gelesen wird: mehr dazu
  20. PNG ist ein Grafikformat: mehr dazu
  21. RGB-Farbtabelle: mehr dazu, noch mehr dazu
  22. Explode zerteilt einen String anhand eines Trennzeichens: mehr dazu
  23. Shuffle() mischt die Elemente eines Arrays: mehr dazu
  24. Imagecolorallocate() bestimmt die Farbe einer Grafik: mehr dazu
  25. Imagestring() zeichnet einen horizontalen String: mehr dazu
  26. Imagepng(): ausgabe eines Bildes an den Browser oder in eine Datei: mehr dazu
  27. Imagedestroy() löscht ein Bild: mehr dazu
  28. Formulare werden verwendet um User Input am Server zu geben: mehr dazu
  29. Header() sendet einen HTTP-Header: mehr dazu


DevilDanny
Rookie
Beitrag vom:
09-09-2007, 13:54:20

Tipp

Man könnte einmal die Eingabe des Users senden und anstatt der Session die richtig Eingabe mit der Funktions "md5" verschlüsseln!!! Anschließend könnte man vergleichen:

if (md5($_POST['usereingabe']) == $_POST['passwort der grafik']) {
RICHTIGE EINGABE
} else {
FALSCHE EINGABE
}

Ansonsten aber optimal!
Danke für den Post :-)

-----------------------------------------------------


g-3nemy
Rookie
Beitrag vom:
19-06-2006, 17:32:54

Hi!
Im Gesamtüberblick ist der Variable $speichern der wert 'zzzz'.$grafik.'.png';
zugewiesen, es muss aber heißen $ 'zzzz'.$grafik_name.'.png';

Und mir ist aufgefallen, dass die Farbauswahl nicht gerade optimal war, da eine bestimmte Kombination nicht lesbar war.

Aber sonst gutes Skript!

Gruß g-3nemy

-----------------------------------------------------


Morraldor
Senior Member
Beitrag vom:
11-10-2004, 17:38:39

oh, ich wußte nicht, dass der Server die Variablen serverseitig speichert.

Danke für die Richtigstellung.

-----------------------------------------------------
Wer dem Leben zu lang zuschaut verpasst es


dreamer
Expert
Beitrag vom:
10-10-2004, 13:37:39

Nur die Session ID wird im Header am Client geleitet. Die andere Variablen bleiben auf dem Server gespeichert. Der Client bekommt diese nie.

-----------------------------------------------------


Morraldor
Senior Member
Beitrag vom:
10-10-2004, 12:45:58

PHP-Session:

Ist es so intelligent PHP-Sessions zu benutzen? Die Session ist eigentlich auch nur ein Cookie oder wird per URL/Formular weitergegeben. Intelligent Spam-Computer oder auf die entsprechende Programmierung spezialisierte könnten das Passwort daraus ohne Probleme rauslesen....

Eventuell könnte man anstelle dessen das Passwort am Server in einer Datenbank speichern und mit der IP-Adresse des Clients verknüpfen.

-----------------------------------------------------
Wer dem Leben zu lang zuschaut verpasst es


[back to top]



Userdaten
User nicht eingeloggt

Gesamtranking
Werbung
Datenbankstand
Autoren:04508
Artikel:00815
Glossar:04116
News:13565
Userbeiträge:16552
Queueeinträge:06246
News Umfrage
Ihre Anforderungen an ein Online-Zeiterfassungs-Produkt?
Mobile Nutzung möglich (Ipone, Android)
Externe API Schnittstelle/Plugins dritter
Zeiterfassung meiner Mitarbeiter
Exportieren in CSV/XLS
Siehe Kommentar



[Results] | [Archiv] Votes: 1154
Comments: 0