Optisches Passwort

von Daniel Arnreich | 1 | 5815 Aufrufe

Anzeige Hier werben

Grundlagen

Bei einer Anmeldung muss der User gewöhnlich sein Benutzername und sein Passwort angeben. Damit das Passwort eine ausreichende Sicherheit bietet, muss es eine gewissen Mindestlänge aufweisen und am besten noch Ziffern und/oder Sonderzeichen enthalten. Solche Passwörter sind dann aber schwer zu merken.

Bekanntermaßen denkt der Mensch in Bildern. Was liegt da also näher als ein "optisches Passwort", bei dem der User mehrere (hier 3) zuvor definierte Punkte in einem (von ihm selbst ausgewählten) Bild anklicken muss?

Dieser Artikel zeigt eine prototypische Umsetzung dieser Idee.

Der HTML/CSS-Teil

Es wird ein DIV-Bereich definiert, der als Hintergrundgrafik das gewünschte Bild aufweist. Darauf wird ein OnClick-Ereignis definiert, durch welches die angeklickte Position ermittelt wird.

 
HTML
1
<div id="img_div" onclick="pw_click(event)" style="background-image:url('img.jpg');width:444px;height:333px;"></div>

Unterhalb der Grafik sollte ein Statusindikator enthalten sein, der angibt, den wievielten Punkt man als nächstes anzuklicken hat:

 
HTML
1
2
3
<div id="stat1" class="stat">1</div>
<div id="stat2" class="stat">2</div>
<div id="stat3" class="stat">3</div>

Der JavaScript-Teil

Die durch das OnClick-Ereignis aufgerufene JavaScript-Methode ermittelt zunächst die angeklickte Position und speichert diese zwischen. Sobald 3 Klicks ausgeführt wurden, werden die gespeicherten Positionen (mittels AJAX [hier umgesetzt mit JQuery]) zur Überprüfung an das Backend gesendet, welches dann mit true (Passwort korrekt) oder false (Passwort falsch) antwortet. In diesem Prototypen ist die einzige Reaktion eine Meldung (alert-Dialog), die das Ergebnis der Überprüfung mitteilt.

Aus diesen Überlegungen ergibt sich folgender Code:

 
JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var clicknr = 1;
var clickPositions = new Array(); //x1, y1, x2, y2, x3, y3

function pw_click(event){

    //Click-Positionen ermitteln
    pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("img_div").offsetLeft;
    pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("img_div").offsetTop;

    //Geklickte Position merken
    clickPositions[(clicknr-1)*2] = pos_x;
    clickPositions[(clicknr-1)*2+1] = pos_y;

    if(clicknr == 3) { //Wenn alle 3 Punkte geklickt wurden...
        $("#stat3").css("background-position", "0px -32px");
    
        //Passwort prüfen
        $.ajax({
            url: "check.php",
            async: false,
            data: "pos="+clickPositions,
            dataType: 'json',
            success: function (ret) {
                if(ret) {
                    alert("Passwort korrekt");
                }
                else {
                    alert("Passwort falsch");
                }
            },
            error: function (xhr, err, txt) {
                alert("Es ist ein Fehler aufgetreten"+err);
            }
        });
        
        //Alles zurücksetzen
        clicknr = 1;
        for(i=1; i<=3; i++) {
            $("#stat"+i).css("background-position", "0px 0px");
        }
        $("#stat1").css("background-position", "0px -32px");
    }
    else {
        //UI auf nächste Eingabe setzen
        for(i=1; i<=clicknr; i++) {
            $("#stat"+i).css("background-position", "0px -32px");
        }
        clicknr++;  
        $("#stat"+clicknr).css("background-position", "0px -64px");
    }   
}

Das Backend

Das Backend berechnet den Abstand der angeklickten Punkte zu den zuvor definierten Stellen. Wenn die Abstände aller 3 Punkte innerhalb einer Toleranz (z.B. 10px) liegen, ist das Passwort korrekt und das PHP-Skript antwortet mit true. (Zur Vereinfachung sind die Koordinaten des korrekten Passworts hier fest im PHP-Skript kodiert.)

 
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
    //Abstand 2er Punkte berechnen
    function distance($x1, $y1, $x2, $y2) {
        return round(sqrt(($x1-$x2)*($x1-$x2)+($y1-$y2)*($y1-$y2)));
    }

    //Fehlertoleranz (=Erlaubte Abweiung im Pixeln vom exakten Punkte)
    $toleranz = 10;

    //Übergebenes Passwort in Komponenten zerlegen (x1, y1, x2, ...)
    $positions = explode(",", $_REQUEST['pos']);
    
    //Korrektes Passwort: (Zu Demonstrationszwecken hart kodiert)
    $correct = array(295,60,211,134,50,155);
    
    if(distance($positions[0],$positions[1],$correct[0],$correct[1])<$toleranz 
        && distance($positions[2],$positions[3],$correct[2],$correct[3])<$toleranz 
        && distance($positions[4],$positions[5],$correct[4],$correct[5])<$toleranz) {
        echo json_encode(true);
    }
    else {
        echo json_encode(false);
    }
?>

Schlussbemerkungen

Dieses hier vorgestellte Beispiel dient lediglich der Demonstration der Idee des optischen Passworts. Für einen produktiven Einsatz sollten noch weitere Sicherheitsmaßnahmen eingebaut werden.

Weiterhin lässt dieser Artikel das Erstellen des Passworts (Auswahl der Punkte, ggf. Upload eines eigenen Bilds, ...) außer Acht. Diese sind für einen produktiven Einsatz jedoch notwendig.

Zum Ausprobieren kann das komplette Beispiel beim Autor per PN angefordert werden. (Der Upload der Datei in diesen Artikel schlug leider fehl.)

Über den Autor: Daniel Arnreich
hat keine Beschreibung angegeben. Eine Beschreibung kann man unter dem Punkt "Profil bearbeiten" im Kontrollzentrum eintragen.
Profilseite betrachten