[php] Anthentification et fonction crypt()

Résolu/Fermé
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009 - 2 mars 2009 à 14:08
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009 - 3 mars 2009 à 00:12
Bonjour,

Je travaille sur un serveur Debian avec Apache2 et php5.

Je souhaite restreindre l'accès à certaines pages de mon site. Pour cela, il est nécessaire d'authentifier les visiteurs. Je stock dans un fichier texte les logins et password de la facon suivante :

user_name1:user_pwd1
user_name2:user_pwd2
...

les chaines user_pwd correspondent aux mots de passe des utilisateurs. Ils sont obtenus à l'aide de la fonction crypt() de php. (instruction : crypt(mot_de_passe); )

Maintenant je veux réaliser le script qui me permettra d'authentifier les utilisateurs.

Je récupère les infos rentrées par le visiteur grâce à des formulaires. Mon script commence comme ça :

$user=$_POST['pseudo'];
$passwd=crypt($_POST['pass']); //pour ne pas que le mot de passe transit en clair

Mon problème arrive ici, lors de la comparaison de mon $passwd avec la chaine que j'ai stockée dans mon fichier texte.


list($user_from_db, $pass_from_db) = explode(":", $ligne_lecture);
//je récupère dans des variables distinctes le nom d'utilisateur et le mot de passe qui étaient contenus dans //mon fichier texte.

if ($passwd == $pass_from_db) {
echo" mot de passe ok" ;
}

Cette condition me renvoie toujours faux et j'ignore pourquoi :(

Pourriez-vous me donnez un coup de pouce ?

Merci d'avance,

Matthieu
A voir également:

18 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 14:23
salut,
list($user_from_db, $pass_from_db) = explode(":", $ligne_lecture);
Est-ce que $ligne_lecture est positionné sur la bonne ligne dans ton fichier ?
Donne aussi par la même occasion le code qui te définit $ligne_lecture.

Cdlt
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 14:27
Hello ! Merci de répondre rapidement :)

voici les infos demandées :


$fichier = fopen($GLOBALS["user_db"], "a+");

if (file_exists($GLOBALS["user_db"])==TRUE){
while(!feof($fichier)){ // Parcourir le fichier tant qu'il n'est pas fini

$ligne_lecture = fgets($fichier, 4096);

list($user_from_db, $pass_from_db) = explode(":", $ligne_lecture);

if ($passwd == $pass_from_db) {
echo" mot de passe ok" ;

}
}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 14:45
Pourquoi utilises-tu $GLOBALS(["user_db"]); et non le nom du fichier ?
Sinon, évite d'ouvrir ton fichier en "a+" si tu as juste besoin de le lire. r suffit amplement.
J'ai également inversé file_exists avec fopen. C'est plus logique de tester si le fichier exister et de l'ouvrir que le contraire.

Ce qui donnerait :
$fileName="tonfichier";
if (file_exists($fileName)) {
    $fichier = fopen($fileName, "r");
    while(!feof($fichier)){  // Parcourir le fichier tant qu'il n'est pas fini
    
          $ligne_lecture = fgets($fichier, 4096);
          list($user_from_db, $pass_from_db) = explode(":", $ligne_lecture);
          echo $user_from_db . ": " . $pass_from_db; //juste pour voir si tout se passe bien. A supprimer après ;-)
          if ( ($user_from_db==$user) && ($passwd == $pass_from_db) {
                echo" authentification ok" 
                break;
          }
    }

    fopen($fichier);
}

Teste ce code. Je t'ai mis une ligne "echo" supplémentaire juste pour que tu puisses voir si la lecture est correcte.
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 15:05
merci de passer un peu de temps pour moi ;)


<?php

$user=$_POST['pseudo'];
$passwd=crypt($_POST['pass']);

$fileName="/var/www/web/dev/db_user";

if (file_exists($fileName)) {
    $fichier = fopen($fileName, "r");
    while(!feof($fichier)){  // Parcourir le fichier tant qu'il n'est pas fini

          $ligne_lecture = fgets($fichier, 4096);
          list($user_from_db, $pass_from_db) = explode(":", $ligne_lecture);
          echo $user_from_db . ": " . $pass_from_db; //juste pour voir si tout se passe bien. A supprimer après ;-)
          if ( ($user_from_db==$user) && ($passwd == $pass_from_db)) {
                echo" authentification ok <br />" ;

          }
          else echo"<br />echec authentifiaction";

    }

    fclose($fichier);
}
?>



voici le résultat :

titi: $1$w1QgP0Ly$qaIMkyoVy/LgxowRZ/kO/0
echec authentifiaction

J'ai vraiment l'impression que le problème se situe au niveau de la fonction crypt() :s


0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonjour

Attention fgets lit jusqu'au caractère de fin de ligne INCLUS. Il faut l'éliminer sinon il se retrouve dans ta variable $pass_from_db

D'autre part, malgré ton commentaire //pour ne pas que le mot de passe transit en clair la fonction crypt n'empêche pas la transmission en clair puisque tu l'appliques en PHP, c'est à dire dans le serveur, c'est à dire qu'il a déjà été transmis
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 15:10
A la place du if.
Mets :
if ( strcmp($user_from_db,$user)==0 && strcmp($passwd,$pass_from_db)==0 ) { 
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 15:10
En réalité j'ai d'autres informations après le mot de passe sur la ligne de mon fichier texte. donc le caractère qui suit le mot de passe sera un ":" Aucun problème de ce coté, donc.

Je n'avais pas vraiment réfléchi à ta remarque concernant la sécurité... La fonction crypt() permet plutot de ne pas stocker le mot de passe en clair. Cette phrase est plus juste.
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 15:13
J'ai remplacé ce que tu viens de dire, mais aucun changement...

Que fait cette fonction ? strcmp() ?

titi: $1$w1QgP0Ly$qaIMkyoVy/LgxowRZ/kO/0
echec authentifiaction
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 15:17
strcmp, c'est utilisé pour de la comparaison binaire.
toto a raison. Il y a le \r ou \r\n de stocker en fin de ligne.
Avant le if, utilise donc l'instruction suivante :
$pass_from_db = preg_replace("/(\r\n|\n|\r)/", "", $pass_from_db);
0
As-tu lu la doc de la fonction crypt ?
C'est normal que ça ne marche pas, crypt utilisé sans le paramètre salt change la valeur de ce paramètre à chaque appel ... tu n'as qu'à essayer
echo crypt ('a'),'<br>',crypt('a');

une solution possible conseillée dans le manuel PHP est d'utiliser le login comme salt.
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 15:47
le salt est alors à utiliser deux fois ? : Lorsque je stock le mot de passe ET quand je crypt() mon mot de passe au début du script d'authentification ?
0
Le plus simple, compte-tenu de ton application, serait d'utiliser MD5, mais si tu tiens à crypt...
Il faut bien que tu l'appelles 2 fois avec le même salt
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 16:03
merci de tes réponses.

A propos de md5, j'en ai également entendu parler, quelle est la différence avec crypt() ?
0
Je te conseille d'aller voir dans la doc PHP pour avoir des informations fiables.
Il s'agit d'algorithmes différents. L'algorithme utilisé par PHP pour la fonction crypt n'est pas forcément toujours le même dépend d'une installation à l'autre (j'espère qu'il ne change pas sur une même installation !! )
L'algorithme MD5 est parfaitement défini, c'est un standard. Il te donnera les mêmes valeurs sur toutes les machines
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 16:09
crypt() peut utiliser MD5. Mais il peut utiliser d'autre fonctions de chiffrement. http://www.manuelphp.com/php/function.crypt.php
Dans ton cas crypt() utilise MD5 (puisque tu obtiens une chaîne hachée commençant par $1$).
Mais vaut mieux utiliser crypt que MD5 puisque crypt mets un salt. Et c'est beaucoup plus sûr. Ou alors, à toi de définir le salt. Par ailleur, vaudrait mieux utiliser sha1 plutôt que md5. Ou encore mieux sha256.
Cdlt
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 21:17
J'ai utilisé le nom d'utilisateur comme salt :
$user=$_POST['pseudo'];
$passwd=crypt($user,$_POST['pass']);

et ceci également lors du stockage du mot de passe dans le fichier texte.

Un nouveau problème est apparu : Admettons que le login soit : bibi et le mot de passe : bibi
Quand je vais rentrer:

- bibi / bibi => OK
- bibi / azerty => accès refusé
- bibi / bib => OK !!!! (et ca marche meme avec bi, ou bibip ...)

0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
2 mars 2009 à 22:34
Oui, mais n'oublie pas qu'il faut aussi vérifier que le nom de l'utilisateur. Et bib n'est pas égal à bibi.
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
2 mars 2009 à 22:35
justement ! c'est un problème que je soulève !! et je ne comprend pas du tout comment c'est possible !!
0
Tu n'es toujours pas allé lire le mode d'emploi de la fonction crypt ?
Visiblement, l'algorithme utilisé ne prend en compte que les 2 premiers caractères du salt. Vérifie la valeur de la constante CRYPT_SALT_LENGTH, elle vaut sûrement 2.
Circonstance aggravante, tu as inversé l'ordre des paramètres passés à crypt, le mot de passe devrait être en premier.

À moins que tu aies des secrets d'état à protéger, utilise MD5. Ce n'est qu'un avis personnel, mais tu vas te simplifier la vie. Des codages plus puissants ne t'apporteront rien sur un site non protégé avec transmission des mots de passe en clair...
0
matthieu60 Messages postés 17 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 3 mars 2009
3 mars 2009 à 00:12
:$ Honte sur moi...inverser les deux paramètres !
Effectivement, ca marche beaucoup mieux ainsi !

Merci à tous les trois de vous êtes penchés sur mon problème :)
0