Cryptage de mots de passes pour un .htaccess

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Cryptage de mots de passes pour un .htaccess

par Sékiltoyai » 23 avr. 2007, 11:11

Sinon tu pouvais utiliser exec('/chemin/htpasswd') pour générer les mots de passe en ligne...
Mais j'ai déjà eu ce problème, c'est bon à savoir qu'il y a une solution simple...

par Cyrano » 23 avr. 2007, 09:04

Excellent, merci beaucoup, je testerai ça à l'occasion. :)

victoire !

par eric21 » 21 avr. 2007, 21:22

:D

Je t'offre la réponse sur un plateau, même si celà ne te sert plus : soyons sport :
<?php 
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; 
}

function encrypt_password_for_apache($plain,$ptype) { 
/* 
  adapted from: 
  http://www.student.oulu.fi/~samiantt/scripts/authuser.php 
*/ 
  switch ($ptype) { 
    case "SHA": // 
      return '{SHA}' . base64_encode(pack('H*', sha1($plain))); 
      break; 
    case "MD5": 
      $salt = generate_salt(8); 
      $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"; 
     break; 
   default: 
     return crypt($plain, generate_salt(2)); 
     break; 
  } 
}
//Appel de la fonction avec le mot de passe 'bikette71'
$plain2=encrypt_password_for_apache("bikette71","MD5");
echo $plain2;
?>

par Cyrano » 20 avr. 2007, 17:02

Salut,
effectivement, du temps à passé depuis ma dernière intervention sur cette question, et j'ai beau réfléchir, d'abord je ne sais plus trop sur quoi je travaillais pour avoir besoin de ce système de sécurité, et ensuite je ne me souviens pas de l'avoir résolu. il y a fort à parier que j'ai du contourner le problème en utilisant un autre système de sécurité par programmation sans .htaccess ni .htpassword.

Désolé de ne pas pouvoir t'aider davantage :?

Script php générant un mot de passe htpasswd

par eric21 » 20 avr. 2007, 15:04

:roll:

Hello !

2 ans après, j'ai le même problème pour produire ce genre de script PHP. As-tu finalement trouvé la solution ?

par Cyrano » 20 janv. 2006, 22:32

Je ferai des tests en rebootant sous Linux demain, on va bien voir. Enfin merci quand même pour le coup de main :)

Je ne mets pas en résolu, d'abord parce que ça ne l'est pas et ensuite parce que je ne désespère pas de trouver une solution.

par Ripat » 20 janv. 2006, 22:25

Tout bien pensé, je ne pense pas que ça vienne de la config Apache. Apache utilise les fonctions de cryptage de l'OS.

Faudrait que tu essayes sur un serveur hébergé.

Tu fais un copier-coller du résultat de crypt() ? Si oui, fais attention à ne pas prendre de caractères inutiles (ne te vexe pas, ça m'est arrivé!)

Par contre, chez moi, un mot de passe en texte clair n'est pas accepté. Apparemment normal sous Linux:
Though htpasswd will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows, Netware and TPF.
D'autres extraits de la page man de htpasswd qui pourraient t'intéresser:
If executed on a Windows system, the password will be encrypted using the modified Apache MD5 algorithm; otherwise, the system's crypt() routine will be used. If the file does not exist, htpasswd will do nothing except return an error.

-m
Use MD5 encryption for passwords. On Windows, Netware and TPF, this is the default.
-d
Use crypt() encryption for passwords. The default on all platforms but Windows, Netware and TPF. Though possibly supported by htpasswd on all platforms, it is not supported by the httpd server on Windows, Netware and TPF.
Relis la dernière phrase, c'est peut-être une piste.

Quelqu'un pour tester sur un autre serveur Windows?

par Cyrano » 20 janv. 2006, 19:15

... Tous les pseudo:mdp que tu donnes là-haut fonctionnent chez moi. ...
Ha... ben ça, il y a des chances pour que ça fasse pas mal avancer le schmilblick : ça veut dire qu'il y a une m**** dans ma configuration de serveur Apache.
Loaded Modules : core mod_win32 mpm_winnt http_core mod_so mod_access mod_actions mod_alias mod_asis mod_auth mod_autoindex mod_cgi mod_dir mod_env mod_imap mod_include mod_isapi mod_log_config mod_mime mod_negotiation mod_rewrite mod_setenvif mod_userdir mod_php5

par Ripat » 20 janv. 2006, 19:09

Ton serveur Apache a bien les mod_auth et mod_access ? (phpinfo)

par Ripat » 20 janv. 2006, 19:03

Le script htpasswd génère des mdp md5 version modifié par Apache. A première vue le salt ressemble à une chaîne cryptée selon l'algo blowfish.
htpasswd encrypts passwords using either a version of MD5
modified for Apache, or the system's crypt() routine. Files
managed by htpasswd may contain both types of passwords;
some user records may have MD5-encrypted passwords while
others in the same file may have passwords encrypted with
crypt().
Cela n'explique pas pourquoi crypt() de PHP ne fonctionne pas. Tous les pseudo:mdp que tu donnes là-haut fonctionnent chez moi. Si tu fais tes tests en local, essaye chez ton hébérgeur (ou l'inverse).

Je regarde du côté de la config apache.

par Cyrano » 20 janv. 2006, 18:07

Si j'utilise ce code, avec le pseudo "Cyrano", le mot de passe "php" et en option de salt "bergerac", j'obtiens les trois versions suivantes :
Standard DES
Cyrano:beeoPwPUZdxNk
crypt md5
Cyrano:$1$BA..095.$xFU1STOGZFyg.gNt4r26R0
crypt md5 et salt perso
Cyrano:$1$bergerac$ksQ2280tsfI/LDNdQ.WRi.
Aucun des trois ne fonctionne.

Si on regarde le même généré avec htpasswd.exe en ligne de commande, j'ai celui-ci :
Cyrano:$apr1$JA2.....$tpjb8Ux.0Owqz9djjH4tX0
La différence majeure que je vois est au niveau de la première partie entre les $$ ainsi que la seconde. htpasswd.exe utilise un salt aléatoire peut-être basé sur une variable de timestamp ou quelque chose dans ce goût-là, aucune idée.
Et là, ça marche. J'aimerais drôlement comprendre l'astuce :?

Note, j'ai posté aussi sur le forum ApacheFrance.com, si on m'y fournit une solution, je sens qu'il va y avoir ici un post documenté dans la FAQ à court terme.

[Edit]
Si je regarde les information données par la ligne de commande :

Code : Tout sélectionner

Usage: htpasswd [-cmdpsD] passwordfile username htpasswd -b[cmdpsD] passwordfile username password htpasswd -n[mdps] username htpasswd -nb[mdps] username password -c Create a new file. -n Don't update file; display results on stdout. -m Force MD5 encryption of the password (default). -d Force CRYPT encryption of the password. -p Do not encrypt the password (plaintext). -s Force SHA encryption of the password. -b Use the password from the command line rather than prompting for it. -D Delete the specified user. On Windows, NetWare and TPF systems the '-m' flag is used by default. On all other systems, the '-p' flag will probably not work.
Il semble que le cryptage MD5 (-m) soit utilisé par défaut sous Windows. Mais comment reproduire la même chose en PHP ?
[/Edit]

par Ripat » 20 janv. 2006, 17:48

Ça ne fonctionne dans aucun cas de figure : les seuls qui fonctionnent pour le moment, ce sont les mots de passes en clair ou ceux cryptés avec l'utilitaire htpasswd.exe en ligne de commande.
Curieux. Essaye ce bout de code pour voir.
// pour générer un mot de passe .htaccess
$user = isset($_POST['user']) ? trim($_POST['user']) : null;
$pass = isset($_POST['pass']) ? trim($_POST['pass']) : null;
$salt = isset($_POST['salt']) ? trim($_POST['salt']) : null;

$salt = substr($salt, 0, CRYPT_SALT_LENGTH );

echo '<form name="form1" method="post" action="'.$_SERVER['PHP_SELF'].'">';
echo '<input name="user" type="text" size="20" value="'.$user.'">';
echo '<input name="pass" type="text" size="20" value="'.$pass.'"><br />';
echo '<input name="salt" type="text" size="20" value="'.$salt.'"> (pour md5 salt perso)<br />';
echo '<input type="submit" name="Submit" value="Confirmer"></form>';

if (CRYPT_STD_DES == 1) {
   echo '<b>Standard DES</b><br />'.$user.':'.crypt($pass, $salt).'<br />';
}

if (CRYPT_EXT_DES == 1) {
   echo '<b>Extended DES</b><br />'.$user.':'.crypt($pass, $salt).'<br />';
}

if (CRYPT_MD5 == 1) {
   echo '<b>crypt md5</b><br />'.$user.':'.crypt($pass).'<br />';
   echo '<b>crypt md5 et salt perso</b><br />'.$user.':'.crypt($pass, '$1$'.$salt.'$').'<br />';
}
Le problème, c'est que quand je m'identifie, on ne me demande qu'un pseudo et un mot de passe, rien d'autre : si j'utilise un grain de sel pour crypter, comment est-ce que je dois faire pour le paramétrer dans mon .htaccess pour que la vérification utilise le même ? C'est en fait surtout ça que je cherche.

À moins que.... faut que je fasse un autre test...
Tu ne dois rien paramétrer. Le salt est contenu dans le mot de passe crypté comme tu peux le voir dans mon post plus haut.

par Cyrano » 20 janv. 2006, 16:51

Ça ne fonctionne dans aucun cas de figure : les seuls qui fonctionnent pour le moment, ce sont les mots de passes en clair ou ceux cryptés avec l'utilitaire htpasswd.exe en ligne de commande. Je dois sûrement oublier un truc quelque part, mais je ne vois pas quoi.

Le problème, c'est que quand je m'identifie, on ne me demande qu'un pseudo et un mot de passe, rien d'autre : si j'utilise un grain de sel pour crypter, comment est-ce que je dois faire pour le paramétrer dans mon .htaccess pour que la vérification utilise le même ? C'est en fait surtout ça que je cherche.

À moins que.... faut que je fasse un autre test...

par Ripat » 20 janv. 2006, 16:39

Si tu invoques simplement crypt($motDePasse), et si ton serveur dispose d'un algo de cryptage md5, le mot de passe sera crypté en md5 avec un salt aléatoire.

Même exemple avec cyrano:php.

cyrano:$1$quqVTGav$rtMP1pD0d99da1oRjYFKZ1

Mais tu peux toujours invoquer crypt() avec un salt de ton choix: crypt($motDePasse, 'bergerac')

cyrano:$1$bergerac$ksQ2280tsfI/LDNdQ.WRi.

Dans mon post plus haut j'ai laissé croire que la fonction php md5() convenait pour crypter un mot de pass pour Apache. Ce n'est pas correct! (fatigue, ou plutôt la paresse --> pas testé).

Utilise donc crypt($motdepasse).

par Cyrano » 20 janv. 2006, 15:06

Bon ok, merci, je vais faire quelques essais, je vous raconterai ;)