Scripts

PIN Login

Edit: Niet geheel veilig mits Man-In-The-Middle ook het plaatje kan opvangen. Als eerste, wie is de Man-In-The-Middle? Als je gegevens stuurt over een onbeveiligde lijn, dan kan iemand tijdens het versturen van de gegevens deze gegevens onderscheppen. Dit is natuurlijk niet leuk als dit bij inloggen gebeurd, omdat je er dan inloggegevens uitlekken. De Man-In-The-Middle kan deze inloggegevens opnieuw gebruiken. Wat kun je doen tegen de Man-In-The-Middle? Nou, eigenlijk niet veel, het enige dat je kunt doen is de gegevens encrypten. Maar dit moet Cliëntside gebeuren. Oplossing: JavaScript. Maar hier zit een nadeel aan: Er zijn mensen die JavaScript uit hebben staan en dan werkt het dus niet. Dan heb je nog een tweede optie: een beveiligde lijn (HTTPS). Hiervoor heb je echter een certificaat voor nodig en deze kost geld. Als je een goede beveiliging wilt hebben raad ik dit je toch sterk aan! Nu heb ik zelf een script gemaakt met een Serverside bescherming tegen de Man-In-The-Middle. Nu zul je je afvragen, hoe kan dat, want de gegevens moeten toch eerst naar de server gaan voor je ze Serverside kunt beschermen. Toch is het mogelijk, door mensen van te voren bepaalde opties te geven (Serverside). Zie het als een PINcode. Je hebt 10 opties: Getallen van 0 tot 9. Nu is een beveiliging met 10 opties natuurlijk niet sterk, je hebt 1/10e kans om het goed te doen, als je gokt. Daarom moet je meerdere getallen invoeren. Hoe meer getallen hoe minder kans op een 'goede gok'. Het aantal opties is te berekenen met 10^n, waarin n het aantal getallen zijn, dus als je 4 getallen moet in te voeren heb je 10^4 opties, dus 10 000 opties. Dit maakt 1/10 000e kans op een 'goede gok'. Hoe maak je dan een PIN, zonder dat de Man-In-The-Middle hier iets aan heeft? Nou, hieronder staat een vereenvoudigde versie van het script dat ik gemaakt heb. Ik zal het principe uitleggen: Je maakt een array en vult deze met waarden van 0 t/m 9. Deze gooi je door elkaar. Nu komt er bijvoorbeeld zoiets uit: Nu zet je deze d.m.v. de GD Lib. in een plaatje: De array sla ik op in een Sessie. De Sessie kan De-Man-In-The-Middle niet lezen, want de sessie blijft alleen op de server. Nu gebruik ik dit plaatje als een . Het voordeel van dit is dat je de precieze plek krijgt doorgestuurd waar de gebruiker klikt (x en y). Nu vernieuwt de pagina en krijgen wij de coördinaten binnen waar de gebruiker gedrukt heeft. Wij weten nog precies hoe het plaatje eruit zag, wij hebben immers de waarden in de sessie staan. Nu slaan we het getal, waar de gebruiker op heeft geklikt, op in een sessie-variabele en zo komen kan de gebruiker zoveel cijfers intikken als deze zelf wil. Ik heb er een voorbeeld bij, let op: Het voorbeeld is veel verder uitgewerkt, de code hieronder is de basis. #ID: Test Pass: test123 PIN: 1234 Voorbeeld();

pin-login
pin.php - Hier word het plaatje gemaakt.

<?php
    session_start();
    $width = (isset($_GET['width']) ? $_GET['width'] : 12);
    $kleurgetal = 200;
    $im = imagecreatetruecolor($width*6-1, $width*8-1);
    $bg = imagecolorallocate($im, 255, 255, 255); // Achtergrondkleur
    imagefill($im, 0, 0, $bg);
    imagecolortransparent($im);
    $getallen = range(0, 9);
    shuffle($getallen);
    $kleuren = array();
    
    // Creëer al dan niet random kleuren.
    $kleur = imagecolorallocate($im, 127, 157, 185);
    for ($i = 0; $i <= 9; $i++)
    {
        $kleuren[$i] = imagecolorallocate($im, $kleurgetal+rand(-20, 20), $kleurgetal+rand(-20, 20), $kleurgetal+rand(-20, 20));
    }
    $x2 = 1;
    $x3 = 1;
    $keys = array();
    for ($i = 0; $i <= 9; $i++)
    {
        // x en y van hokjes bepalen
        if ($i == 9)
        {
            $x2 = 3;
            $x3 = 2;
        }
        $y = floor($i/3);
        $x = $i-$y*3;
        
        // Vierkantjes waar cijfers in gaan.
        imagefilledrectangle($im, ($x*2)*$width, ($y*2)*$width, ($x*2+2)*$width*$x2-2, ($y*2+2)*$width-2, $kleuren[$i]);
        imagerectangle($im, ($x*2)*$width, ($y*2)*$width, ($x*2+2)*$width*$x2-2, ($y*2+2)*$width-2, $kleur);
        
        // Schuine lijntjes - opleuking
        for ($i2 = 0; $i2 < ($width*$x3)-1; $i2++)
        {
            imageline($im, (($i2*2)+1)+($x*2)*$width, ($y*2)*$width, ($x*2)*$width+1, (($i2*2)+1)+($y*2)*$width-1, $kleur);
        }
        
        // Sessie waarin staat op welke plaats welk nummer staat.
        imagechar($im, 5, ($x*2+1)*$x2*$width-5, ($y*2+1)*$width-8, $getallen[$i], $kleur);
        $_SESSION['keys'][$i] = $getallen[$i];
    }
    
    // Show image
    header('Content-Type: image/gif');
    imagegif($im);
    imagedestroy($im);
?> 

functions.php - functie die handig is bij elke pagina waar je de PIN gebruikt. Hier kun je nog extra functies bij maken die handig zijn voor een PIN.

<?php
    // Controle welk cijfer ingedrukt is.
    function pin_click ()
    {
        global $width;
        $x = floor($_POST['pin_x']/($width*2));
        $y = floor($_POST['pin_y']/($width*2));
        $place = $x+$y*3;
        if ($place > 9)
        {
            $place = 9;
        }
        
        if (isset($_SESSION['keys'][$place]))
        {
            $_SESSION['pin'][] = $_SESSION['keys'][$place];
        }
    }
?> 

page.php - Een vereenvoudigde pagina met PIN. 

<?php
    session_start();
    // Als Sessie-IP niet gelijk is aan Gebruiker-IP
    if (isset($_SESSION['ip']) && $_SESSION['ip'] != $_SERVER['REMOTE_ADDR'])
    {
        unset($_SESSION);
        session_destroy();
        session_start();
    }
    $width = 12;
    include('functions.php');
    
    // Zet sessie, als deze nog niet geset is.
    if (!isset($_SESSION['ip']))
    {
        $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
        $_SESSION['pin'] = array();
    }
    
    // één of alle tekens van de PIN wissen, bij indrukken van Del of Clear.
    if ($_POST['action'] == 'Clear' or $_POST['action'] == 'Del')
    {
        if ($_POST['action'] == 'Clear')
        {
            $_SESSION['pin'] = array();
        }
        if ($_POST['action'] == 'Del')
        {
            unset($_SESSION['pin'][(count($_SESSION['pin'])-1)]);
        }
        unset($_POST['action'], $_POST['pin_x'], $_POST['pin_y']);
    }
    
    // Controleren welk getal ingetoetst is.
    if (isset($_POST['pin_x']) && isset($_POST['pin_y']))
    {
        pin_click();
    }
    $totpin = count($_SESSION['pin']);
    $tekens = '';
    for ($i = 0; $i < $totpin; $i++)
    {
        $tekens .= '*';
    }
    echo 'Pin: '.$tekens;
    echo '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
    echo '<input type="image" name="pin" src="pin.php?width='.$width.'" alt="PIN"/>';
    echo '<br/ ><input type="submit" name="action" value="Del"><input type="submit" name="action" value="Clear">';
    echo '</form>';

?> 

Reacties

0
Nog geen reacties.