Sahid Ferdjaoui Blog - Funraill Foundation Bienvenue, Log in - thème 2007 RC1

Powered by OpenSource Softwares

Outil de déboggage colaborative
reduire

PHP AJAX - HTTP Identification avec Cryptographie Asymétrique

le 4 novembre 2006 par sahid

Une identification PHP/AJAX utilisant la Cryptographie Asymétrique

Voila une maniÚre d’aborder AJAX, on va essayer de mettre au point un systÚme d’identification
des utilisateurs avec PHP/MySQL, mais aussi en utilisant
de l’AJAX histoire de rester dans le web 2.0 …de plus pour agrémenter un peu les choses on utilisera une technique de cryptographie asymetrique tiré de RSA, cela peut être utile si vous n’avez pas les moyens ou pas envie d’acquerir une clef ssh valide.

Identification PHP AJAX RSA

Principe de la Cryptographie Asymétrique

En gros, dans notre cas,
On a un mot de passe crypteé en MD5 en base de donnée. Le serveur génere une clef publique qu’il garde en session et l’envoi au client, cette clef sera le facteur commun entre le serveur et le client.
Notre client envoi la clef publique, le mot de passe haché une premiere fois avec l’algorithme MD5, et une deuxieme fois avec la clef publique.
Donc le serveur recoit un mot de passe haché avec la clef publique, et la clef publique, il n’a plus qu’a verifier que la clef publique envoyée est bien identique à la sienne gardeée en session, et recuperer le mot de passe crypté en MD5 de la base de donnée, le hacher avec la clef publique et verifier que les deux mots de passe (celui envoyé par le client haché avec la clef publique, et celui recuperé de la DB hacher avec la clef publique) correspondent.

Cahier des charges :

Soyons pro un cahier des charges peut etre interessant histoire de savoir ou on met les pieds.
Notre projet visera la simplicité, (…je ne suis pas reponsable si vous vous faites hacker !! lol …)

  • Tournera sur Firefox et Internet Explorer
  • Les utilisateur n’ayant pas activé JS pour X raisons, pourront quand meme se logger ( ou non … a vous de voir)
  • Une petite console, histoire de voir les échanges client serveur
  • je reflechis !

Prerequit :

On utilisera deux bibliotheques permettant un hash md5, une en Javascript et l’autre en PHP, elle sont dans l’archive.

C’est parti !

Je ne vais pas detailler pas à pas le projet, juste donner la methode … (je n’ai pas dis non plus que c’etait la meilleure !)
pourquoi ? … parce qu’au moment ou j’ecris ces lignes, j’ai faim … ensuite parce que je laisse les sources du projet,
puis faire des petites recherches personnelles c’est le mieux.

Le Client

Pour la partie client, en premier, on va initialiser une clef publique qui sera envoyée au serveur par l’intermediaire du formulaire

  1. $_SESSION[‘cle’] = uniqid(mt_rand(), true);          // génération d’une clé publique unique
  2.  

maintenant on va mettre en place un formulaire qui sera envoyé seulement apres avoir recu l’accord de la methode
javascript httpRequest(), qui, elle, acceptera l’envoi du formulaire seulement si l’utilisateur n’a pas activé Javascript, dans le cas
contraire, elle utilisera la methode HTTPRequestXML pour envoyer les informations du formulaire au serveur

  1. <form method=“POST” action=“serveur.php” id=“formCrypt” onsubmit=“return httpRequest()”>
  2.         <input type=“hidden” id=“js” name=“js” value=“0″/>
  3.         <label>
  4.                 <input type=“text” id=“cle” name=“cle” value=“<?=$_SESSION[’cle’]?/>" size="33" disabled/>
  5.                 Clef publique<br />
  6.         </label>
  7.         <label>
  8.                 <input type=”text” id=”username” name=”username” size=”33“/>
  9.                 Nom d’utilisateur<br />
  10.         </label>
  11.         <label>
  12.                 <input type=”password” id=”password” name=”password” size=”33“/>
  13.                 Mot de passe<br />
  14.         </label>
  15.         <input type=”submit” id=”submit” name=”submit” value=”Connexion S&eacute;curis&eacute;e“/>                 
  16. </form>

La methode httpRequest, est en fait celle qui va gérer les requêtes avec le serveur, seulenemt avant d’envoyer la requête,
on a besoin d’hacher le mot de passe avec la clef publique generée au préalable.

  1. function httpRequest() {
  2.         var request;
  3.         var p, u, c;
  4.  
  5.         // instance de l’objet pour la communication avec le serveur
  6.         if ( window.XMLHttpRequest ) {
  7.             request = new XMLHttpRequest();
  8.             request.overrideMimeType(‘text/xml’);       // force l’en-tete des reponses en XML
  9.         } else if ( window.ActiveXObject ) {
  10.             request = new ActiveXObject(“Microsoft.XMLHTTP”);
  11.         }
  12.  
  13.         // impossible d’utiliser AJAX
  14.         if (!request) {
  15.                 return true; // envoi du formulaire normal !
  16.         }
  17.        
  18.         // — Traitement des données du formulaire
  19.         u = $(‘username’);
  20.         p = $(‘password’);
  21.         c = $(‘cle’);
  22.        
  23.         // hachage du password avec la clef publique (le mdp est aussi haché en md5)
  24.         p.value = hex_hmac_md5(c.value, hex_md5(p.value));
  25.  
  26.         // — Traitement des reponses du serveur
  27.         request.onreadystatechange = function() { traitement(request) }
  28.  
  29.         request.open(‘POST’, ’serveur.php’, true);                                                      // préparation de la requête
  30.         request.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);
  31.         request.send(‘username=’+u.value+‘&password=’+p.value+‘&cle=’+c.value+‘&js=1′);  // envoi de la requête
  32.        
  33.         return false; // évite l’envoi du formulaire
  34. }

Donc maintenant on est prêt a envoyer une requete au serveur avec un mot de passe crypté qui nous evitera ainsi de se faire sniffer par des
méchants pirates !; la methode traitement(), elle, reagit aux reponses du serveur

  1. function traitement( request ) {
  2.         // vérification de l’état de la requête ( 4 = terminée )
  3.         switch (request.readyState) {
  4.                 case 0 :                                                                                                // 0 non initialisé
  5.                         affiche(‘requ&ecirc;te non initialisée !’)
  6.                 break;
  7.                 case 1 :                                                                                                // en cours de chargement
  8.                         affiche(‘requ&ecirc;te en cours de chargement …’)
  9.                         onLoad();
  10.                 break;
  11.                 case 2 :                                                                                                // chargée
  12.                         affiche(‘requ&ecirc;te charg&eacute;e !’)
  13.                         offLoad();
  14.                 break;
  15.                 case 3 :                                                                                                // en cours d’interaction avec le serveur
  16.                         affiche(‘requ&ecirc;te en cours de d\’int&eacute;raction avec le serveur …’)
  17.                 break;
  18.                 case 4 :                                                                                                // terminée   
  19.                         affiche(‘requ&ecirc;te termin&eacute;e !’);
  20.                         if ( request.status == 200 ) {
  21.                                         reponse(request.responseXML);
  22.                         } else
  23.                                 affiche(‘Un probl&egrave;me est survenu avec la requ&ecirc;te’);
  24.                 break;
  25.         }
  26. }

Le serveur

Voyons un peu comment le serveur doit nous retourner les reponses,
Deja on veut de l’AJAX, donc elles nous seront retournées en XML, javascript manie plutot bien le DOM.

j’utilise une classe pour l’identification que je ne presenterai pas ici, elle sera dans les sources a telecharger

  1. // Javascript est actif, Traitement AJAX
  2. if ( $js === 1 ) {
  3.         $con = new Cryptographie($_SESSION[‘cle’]);
  4.        
  5.         usleep(800000)// simulation de délai en local
  6.        
  7.         $cle = $con->checkCle($_POST[‘cle’]);
  8.         if ( $cle ) {
  9.                 $db_mdp = $con->checkUsername($_POST[‘username’]);
  10.                 if ( $db_mdp !== false )
  11.                         $ok = $con->checkPassword($db_mdp, $_POST[‘password’]);
  12.         }
  13.                        
  14.         $erreurs = $con->erreurs;
  15.        
  16.         header(‘Content-type: text/xml’);
  17.         if ( count($erreurs) !== 0 ) {
  18.                 foreach ( $erreurs as $num => $erreur )
  19.                         echo ‘<xml><numero>’.$num.‘</numero><message>’.$erreur.‘</message></xml>’;
  20.         } else {
  21.                 //$_SESSION[’user’] = $_POST[’username’];       // - on ouvre une session, l’utilisateur est connecté !
  22.                 echo ‘<xml><numero>0</numero><message>CONNEXION_ACCEPTEE</message></xml>’;
  23.         }
  24. } else {
  25.         // traitement normal
  26.         echo ‘js n\’est pas actif !’;
  27. }

La console

Dans le cahier des charges on a parlé de créer une console afin de voir un peu comment reagit notre code …
ca sera en fait une simple fonction javascript qui nous permettra de sonder chaque partie du code que l’on souhaite.

  1. function affiche(msg) {
  2.         $(‘console’).innerHTML += “< ?=$_SERVER[’REMOTE_ADDR’]?> : “+msg+“<br />”;
  3. }

Cryptographie PHP/MySQL -AJAX - RSA

Un commentaire pour PHP AJAX - HTTP Identification avec Cryptographie Asymétrique

  1. msalek dit :

    bonsoir,
    c trés bien comme script mais je vois que c pas terminer,
    je pense que il faut mettre une redirection et un entete qui controle la session,

    on tous cas merci bcp
    bonne chance

Tu peux laisser un commentaire pour PHP AJAX - HTTP Identification avec Cryptographie Asymétrique