Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1780 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  [RESOLU] htaccess, htpasswd, md5, salt, validation password par php

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[RESOLU] htaccess, htpasswd, md5, salt, validation password par php

n°1912808
Zokreb
Posté le 07-08-2009 à 13:00:52  profilanswer
 

Bonjour tout le monde
 
La problématique est la suivante. J'ai un dossier protégé par .htaccess et .htpasswd.
Je souhaite faire une page de modification du fichier .htpasswd (ajout d'utilisateur ou changement de mot de passe) (placée dans le même répertoire que htaccess et htpasswd). A priori donc, seuls les gens ayant le mot passe du htpasswd peuvent voir cette page. Mais, comme je suis parano :euh: , lors du changement de mot de passe, je demande à mon utilisateur son ancien mot de passe. Avec wamp, tout va bien, je compare le mot de passe récupéré avec le POST avec $_SERVER['PHP_AUTH_PW']. Si c'est correct, j'autorise le changement de passe.
 
Mais voilà, l'hébergeur interdit l'utilisation $_SERVER['PHP_AUTH_PW'] (ce qui doit pas être plus mal finalement).
Le mot de passe dans le .htpasswd est codé avec la fonction md5_apr1 présente ici : http://www.phpbuilder.com/tips/item.php?id=991 Il s'agit de la même fonction de codage md5 présente dans l'executable htpasswd.exe fournie avec Apache 2.2. sauf qu'elle est en php.
 
Je précise aussi que tous les mots de passe générés par cette fonction 'maison' sont validés lorsque que je me logue par htaccess. l'ennui, c'est qu'un même mot de passe donne des hash différents à chaque fois qu'il est crypté. ex :
 

crypt_apr1_md5('motdepasse')."<br>".crypt_apr1_md5('motdepasse')."<br>".crypt_apr1_md5('motdepasse')."<br>";

donnera :
 
$apr1$pTr2AOpI$dsTwuEcstcKDQfI9y3iKn.
$apr1$MLGRZWex$ReGam3wuaDTySxcjxPa0p1
$apr1$bbsZplNF$w7GEYf5TXmK5LHGItX8Vg1

 
Si apache arrive à reconnaitre tous ces mots de passe comme valides, il doit bien y avoir un moyen de valider le mot de passe entré par l'utilisateur non ?
 
Avec une fonction sha1 par exemple, pour comparer le mot de passe avec celui présent dans le .htpasswd, on peut faire
if(sha($MonMotDePasse) == $motDePasseDuHtpasswd) echo 'OK';
car le hash donné par la fonction sha ne varie jamais sur un meme mot de passe. Par contre, avec le md5 tel qu'il est généré par htpasswd.exe, je ne peux pas comparer. Comment faire ici donc ?
 
N'hésitez pas à me demander plus amples informations, car je sais que je peux ne pas être clair  :p


Message édité par Zokreb le 07-08-2009 à 19:28:38
mood
Publicité
Posté le 07-08-2009 à 13:00:52  profilanswer
 

n°1912913
Taiche
(╯°□°)╯︵ ┻━┻
Posté le 07-08-2009 à 15:12:56  profilanswer
 

Apache indique sur la page de doc adéquate comment valider le password codé.
 
Sinon, puisque tu sais faire avec SHA, pourquoi tu utilises pas cet algo pour générer ton password ?


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
n°1913017
Zokreb
Posté le 07-08-2009 à 19:27:19  profilanswer
 

Pour répondre à ta question "pourquoi ne pas utiliser SHA ?" :
Je suis un quiche en cryptographie, mais il parait que c'est mal de voir 2 fois le même mot de passe crypté sur une page (au cas où deux personnes utiliseraient le meme mot de passe). Du coup, j'ai aucune idée de pourquoi, mais je m'exécute, je préfère utiliser la méthode avec le sel (le salt quoi) qui donne des mdp toujours différents.
 
Cela dit, avec tes infos, j'ai pu me dépatouiller. Le site proposait une validation à partir du programme openSSL, mais voilà, dans php, c'est pas implémenté à coup sûr suivant les hébergeurs. Alors j'ai voulu faire pareil avec la fonction PHP maison.
Pour les futurs visiteurs que ca intéresserait :
 
Lorsque le mot de passe est généré par apache, il est généré sous la forme suivante : $apr1$bbsZplNF$w7GEYf5TXmK5LHGItX8Vg1
la première partie $apr1 sert à indiquer à apache quel est le codage utilisé. La deuxième partie $bbsZplNF est le "sel" non crypté qui est généré par une fonction à part. Enfin, la troisième partie correspond à notre mot de passe auquel a été concaténé le sel au cours du processus de hash (qui comprend je le rappelle 1000 md5 successifs dans le cas de l'authentification apache, mais ca on s'en fout).
autrement dit, pour comparer le mot de passe il nous faut aussi le sel et on met les deux à la moulinette.
 
Du coup, j'ai légèrement modifié la fonction présente sur le site http://www.phpbuilder.com/tips/item.php?id=991 pour passer à la fois le mot de passe et le sel.
 
La fonction est donc la suivante :
 


function crypt_apr1_md5($plain,$salt) {
      $length = strlen($plain);
      $context = $plain . '$apr1$' . $salt;
      $binary = pack('H32', md5($plain . $salt . $plain));
      for($i = $length; $i > 0; $i -= 16) {
        $context .= substr($binary, 0, min(16, $i));
      }
      for($i = $length; $i > 0; $i >>= 1) {
        $context .= ($i & 1) ? chr(0) : $plain{0};
      }
      $binary = pack('H32', md5($context));
      for($i = 0; $i < 1000; $i++) {
        $new = ($i & 1) ? $plain : $binary;
        if ($i % 3) $new .= $salt;
        if ($i % 7) $new .= $plain;
        $new .= ($i & 1) ? $binary : $plain;
        $binary = pack('H32', md5($new));
      }
      $q = '';
      for ($i = 0; $i < 5; $i++) {
        $k = $i + 6;
        $j = $i + 12;
        if ($j == 16) $j = 5;
        $q = $binary{$i} . $binary{$k} . $binary{$j} . $q;
      }
     $q = chr(0) . chr(0) . $binary{11} . $q;
     $q = strtr(strrev(substr(base64_encode($q), 2)),
                'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
                './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
     return "\$apr1\$$salt\$$q";
}
function generate_salt($len) {
  $randset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  $randset .= './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  $salt = "";
  for ($i=0;$i<$len;$i++) {
    $choice = rand(0,strlen($randset)-1);
    $salt .= (substr($randset,$choice,1));
  }
  return $salt;
}


 
Pour générer le mot de passe une premiere fois, on l'appelle par :
 

crypt_apr1_md5($motdepasse,generate_salt(8));


 
ensuite, on récupère les infos contenues dans le fichier .htpasswd par exemple comme ca :
 


$rowuser=substr($row,0,strlen($user.':'));
$rowsalt=substr($row , strlen($user.':$apr1$'),8);
$rowpasswd=substr($row , strlen($user.':') , 37);


 
et on peut comparer le mot de passe de l'utilisateur avec :
 

if($rowpasswd!=crypt_apr1_md5($motdepasse,$rowsalt))


 
Voilà, j'ai bien conscience de pas avoir inventé la poudre, mais chuis content d'avoir compris ça car ça me prenait la tête depuis hier.
 
Merci


Message édité par Zokreb le 07-08-2009 à 19:31:27

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  [RESOLU] htaccess, htpasswd, md5, salt, validation password par php

 

Sujets relatifs
[Résolu] Macro - Importation .csv en UTF-8[Resolu] Deziper un fichier en vbs
Headers et headers_sent (Résolu)[RESOLU] Acc. 2000 Export XL : contourner la limite de 255 caractères
Gros problème de Mappage de lecteurs réseaux [ Résolu][résolu] Warning: Call-time pass-by-reference has been deprecated
[Résolu] Un bouquin en ASP ?VB Lancer un .bat tout juste créé [Resolu]
socket pas thread safe sous linux ? si en fait (resolu)[RESOLU] erreur pendant le chargement un fichier XML
Plus de sujets relatifs à : [RESOLU] htaccess, htpasswd, md5, salt, validation password par php


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR