Securite Informatique - novembre 2006 - L©S ßlog - CyberSDF

L©S ßlog - CyberSDF

jeudi 23 novembre 2006

Authenfication forte pour pas un rond (ou presque)

Si vous êtes comme moi, vous ne faites qu'une confiance partielle aux différents couples de login et mot de passe.
En effet, sans même entrer dans le détail du nombre de petits programmes espions que pourrait contenir votre ordinateur ou de quelqu'un qui écoute votre réseau, n'importe qui peut regarder derrière votre épaule et voir vos identifiants.

Pour pallier à tout ça, il a été inventé le principe d'authentification forte[1] que j'ai déjà introduit dans ce blog.

Pour mémoire, le concept de l'authentification forte repose sur l'utilisation d'au moins deux facteurs parmi les suivants :
- Ce que l'utilisateur connaît (login, un mot de passe, un code PIN),
- Ce que l'utilisateur détient (une carte magnétique, une carte à puce, un « authentifieur »),
- Ce que l'utilisateur est (empreinte digitale, empreinte rétinienne, structure de la main, structure osseuse du visage ou tout autre élément biométrique)

On voit donc des solutions arriver, que ce soit en biométrie ou des secureID à mettre autour du cou, etc.
Le hic, c'est que toutes ces technologies coûtent de l'argent (et pas qu'un peu pour certaines d'entre elles), et moi de l'argent, je vous avoue que je n'en ai pas beaucoup...
Pourtant, pour certaines applications (quelles qu'elles soient) j'aimerais bien leur proposer une authentification forte quand même. Comment faire ?

Et bien je vais vous donner une méthode simplissime qui ne vous coûtera pas un rond !

Le principe général

Bon déjà on oublie la biométrie, donc ce que l'utilisateur est on met de côté.
On se concentre donc sur ce que l'utilisateur connaît et ce que l'utilisateur détient.

L'idée est de fournir à votre utilisateur (en plus d'un nom d'utilisateur et d'un mot de passe) une carte du style bataille navale de n colonnes sur n lignes (tout dépend de ce que vous voulez faire).

Votre utilisateur entre donc son login (CyberSDF) et son password (12345678), l'application le reconnaît (elle peut même lui dire bonjour) et, pour confirmer que c'est bien CyberSDF himself qui veut se connecter, lui demande la valeur de la case D7 de SA carte. Il cherche partout sa carte, la trouve, cherche la case D7, entre la valeur 2e68 et envoie.
Si la réponse est correcte, le serveur lui donne l'accès, sinon l'envoie bouler.

La réalisation (en php)

Créer la carte

Là vous me dites, t'es bien gentil mais comment je fais pour lui créer ta carte de bataille navale ?
Rien de plus simple ! Tout ce dont vous avez besoin c'est de son login (normalement ça devrait être bon) et d'un grain de sel[2], qui est associé à l'utilisateur qui sera stocké quelque part.

Aller, le bout de code et on explique après :

[php]
<?php
function gencard($login='CyberSDF',$salt18 = 'voilàmongraindesel') {  

 $temp = md5($login.$salt18);
 $alphabet = 'ABCDE';

 for($i=1; $i<=5; $i++) {
  for($j=0; $j<5; $j++) { 
   $foo[$i][$alphabet[$j]] = dechex( (ord($temp[$i])*ord($temp[$j])) );
  }
 }
 return $foo;
}
?>

Voilà une fonction qui nous génère notre carte de 5 colonnes sur 5 lignes dans un tableau à deux dimensions.

  1. Je fais un MD5 du login et du grain de sel histoire d'avoir quelque chose sur 32 caractères ;
  2. Mon tableau aura 10 colonnes, donc 10 lettres de l'alphabet ;
  3. Je commence une boucle de 1 à 5 inclus ;
  4. Je met une seconde boucle de 0 à 5 exclu ;
  5. Je crée mon tableau multidimensionnel déjà indexé avec les bons chiffres et lettres ;
  6. Je renvoie le tableau.

Pour le remplissage du tableau, je me suis inventé un petit truc où je multiple les valeurs ASCCI de deux lettres et je transforme le résultat en hexadécimal. Pourquoi de l'hexa ? Tout simplement pour avoir de temps en temps des lettres, je trouve juste que c'est plus sympathique :-)

Deux mises en garde tout de même [3] :
- Mon modèle mathématique est horrible !!! En effet, si vous comptez bien, je ne peux créer qu'une carte de 32 cases (mon MD5) donc pour une carte d'au-delà de 5*5 il y a forcement des répétitions. Le but ici n'est pas de vous donner le meilleur modèle mathématique mais de vous présenter le principe, charge à vous de faire votre propre machin.
- Le grain de sel ne doit pas être transmis en clair (pour le login on s'en fiche)

Afficher la carte

Là, rien de plus simple, c'est un simple parcours de tableau :

[php]
<?php $bar = gencard(); ?>
<table border="1" cellpadding="5">
 <tr>
  <th>&nbsp;</th>
  <?php
  $alpha = 'ABCDE';
  for($j=0; $j<strlen($alpha); $j++) {
  echo "  <th>".$alpha[$j]."</th>\r\n";
  }
  ?>
 </tr>
  <?php
    for($i=1; $i<=10; $i++) {
       echo " <tr>\r\n  <th>".$i."</th>\r\n";
       for($j=1; $j<=strlen($alpha); $j++) {
          echo "  <td>".$bar[$i][$alpha[$j-1]]."</td>\r\n";
       }
       echo "</tr>\r\n";
     }
 ?>
</table>

Demander une case

On a généré la carte qui va bien, notre utilisateur l'a imprimée, il ne reste plus qu'à l'utiliser.

On lui demande une case au pif :

[php]
<?php
$ltr = 'ABCDE';
echo $case = $ltr[mt_rand(0,4)].mt_rand(1,5);
?>

Notre utilisateur envoie à l'application le contenu de la case, et pour vérifier le résultat il n'y a plus qu'à recréer la carte (sans l'afficher bien sûr) et de comparer la valeur trouvée avec la valeur envoyée.

[php]
<form method="post" id="monform" name="monform" action="<?php echo $_SERVER['PHP_SELF'] ?>">
 <input type="text" id="val" name="val" /> 
 <input type="hidden" id="case" name="case" value="<?php echo $case ?>" />
 <input type="submit" />
</form>
[php]
<?php
function verifcase() {
 if($_REQUEST['val']!='') {
  $plop = gencard();
  if($plop[substr($_REQUEST['case'],1,2)][substr($_REQUEST['case'],0,1)] == $_REQUEST['val'])
   return true;
  else
   return false
 }
}
?>

Et voilà ! Simple comme tout non ?

Si jamais vous voulez voir ça en action, j'ai fait une démo

Notes

[1] Faudra que quelqu'un pense à compléter ça http://fr.wikipedia.org/wiki/Authentification_forte

[2] Une explication de la technique du grain de sel très claire

[3] Si vous utilisez mon code tel quel, c'est à vos risques et périls hein

Toutes les fautes d'orthographes présentes sur ce site sont protégées par la licence Logo Creative common Creative common

 |  Valid XHTML  |  Valid CSS  |  Dotclear  |  Design décliné de [ON]Simple par [ NikO ]
Hébergé par Typhon.Network