Page 1 sur 2

Cryptage de mots de passes pour un .htaccess

Posté : 20 janv. 2006, 12:22
par Cyrano
Bonjour,
je m'interroge sur le fonctionnement de la gestion des mots de passe dans un fichier .htaccess par Apache.

En faisant des tests en local, j'ai un peu de difficulté à trouver la bonne manière pour crypter un mot de passe.

Si je mets le mot de passe en clair dans le fichier, ça fonctionne;
Si j'utilise la ligne de commande de htpasswd.exe pour crypter mes mots de passe, ça fonctionne aussi, mon identification se passe normalement;

En revanche, si j'essaye de crypter mes mots de passe en PHP avec crypt() ou md5(), je me fais jeter lors de l'identification. La doc Apache2 est assez peu loquace sur le sujet, est-ce que quelqu'un aurait des informations pratiques à me suggérer ?

Notez que j'ai déjà fait le tour de commentcamarche.net ou encore de webmaster-hub.com mais je cale un peu sur ce problème.

Posté : 20 janv. 2006, 12:49
par Ouaibou
Salut,

Je sais pas si ça peut t'aider mais j'ai trouvé ça sur google et ça parle un peu du mécanisme d'encryptage, des mots de passes... (plutôt vers la fin de la page)

http://www.infres.enst.fr/~danzart/frames/htaccess.html

@+

Posté : 20 janv. 2006, 12:51
par Cyrano
Merci, je vais regarder ça ;)

Posté : 20 janv. 2006, 13:46
par Cyrano
Bon, ça ne m'avance malheureusement pas. Le problème, c'est que j'ignore quel algorithme de cryptage/hashage utilise htpasswd.exe : Il semble que la fonction crypt() soit appropriée, mais à condition d'utiliser le bon "grain de sel" : or je ne sais pas trop comment il est défini via la ligne de commande.

En local, je peux le faire en ligne de commande, pas de problème, mais une fois en ligne, je n'aurai certainement pas accès à cet utilitaire Apache, je devrai donc crypter les mots de passe moi-même.

Si je n'utilise pas de "grain de sel", PHP va le gérer lui-même. Très bien, mais ça pose un problème lors de l'identification puisque comme c'est un haschage, le contrôle se fait par haschage du mot de passe proposé : le "grain de sel" étant géré par PHP, il a toutes les chances d'être différent de celui utilisé à la création.

Donc comment contrôler le "grain de sel" dans le fichier .htaccess ?

Où alors j'ai loupé quelque chose quelque part :-k

Posté : 20 janv. 2006, 14:29
par Ouaibou
---

Posté : 20 janv. 2006, 14:53
par Ripat
J'utilise indiféremment:
crypt($mdp);
crypt($mdp, base64_encode(CRYPT_STD_DES);
md5($mdp);
Ce qui donne pour
user: cyrano
pass: php

Code : Tout sélectionner

crypt() cyrano:$1$cv1oudjU$qskwshFBX0CvZqaZa8e4p1 (entre autres...) crypt base 64 cyrano:MQgnBhThTQenE md5 cyrano:e1bfd762321e409cee4ac0b6e841963c

Posté : 20 janv. 2006, 15:06
par Cyrano
Bon ok, merci, je vais faire quelques essais, je vous raconterai ;)

Posté : 20 janv. 2006, 16:39
par Ripat
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).

Posté : 20 janv. 2006, 16:51
par Cyrano
Ç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...

Posté : 20 janv. 2006, 17:48
par Ripat
Ç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.

Posté : 20 janv. 2006, 18:07
par Cyrano
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]

Posté : 20 janv. 2006, 19:03
par Ripat
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.

Posté : 20 janv. 2006, 19:09
par Ripat
Ton serveur Apache a bien les mod_auth et mod_access ? (phpinfo)

Posté : 20 janv. 2006, 19:15
par Cyrano
... 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

Posté : 20 janv. 2006, 22:25
par Ripat
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?