Cryptage d'un mot de passe puis comparaison

Cryptage d'un mot de passe puis comparaison - PHP - Programmation

Marsh Posté le 19-05-2006 à 12:11:38    

Bonjour,
J'ai actuellement un formulaire de login qui fonctionne bien, mais les mots de passe sont stocker en clair dans ma base MySQL, et maintenant que je vais utiliser plus sérieusement ma petite application, je souhaite la sécuriser un peu mieux.
J'ai fait pas mal de recherche sur le web pour essayer de trouver quelque chose d'intéressant, mais pour l'instant c'est pas très fructueux.
Je précise que le mot de passe peut être changer depuis la base de donnée seulement. Je ne souhaite pas faire de formulaire pour changer le mot de passe, ni pour créer des utilisateurs.
Est-ce que quelqu'un peut me conseiller?
Voici ma page de login actuelle.

Code :
  1. <?
  2. /*
  3. ---------------------------------------------------------
  4. Module : Login form
  5. Auteur : Thomas
  6. ---------------------------------------------------------
  7. */
  8. /*
  9. -------------------------
  10. On appelle les librairies
  11. -------------------------
  12. */
  13. include('lib/connection.lib.php');
  14. include('lib/erreur.lib.php');
  15. if($QUERY_STRING =='logout')
  16. {
  17. session_unset();
  18. //destruction de session
  19. session_destroy();
  20. //redirection vers page d'accueil
  21. unset($_POST['send']);
  22. }
  23. if(isset($_POST['send']))
  24. {
  25. $login = $_POST['login'];
  26. $pwd = $_POST['pwd'];
  27. $requete = "select * from `te_utilisateur` where `utillog`='$login'";
  28. $envoi = mysql_query($requete)
  29. or die($errReq);
  30. $tableau = mysql_fetch_array($envoi);
  31. // on stock le contenu de l'enregistrement dans plusieurs variables
  32. $id = $tableau['utilnum'];
  33. $login = $tableau['utillog'];
  34. $pwd_valide = $tableau['utilmdp'];
  35. $type = $tableau['utiltyp'];
  36. $nom = $tableau['utilnom'];
  37. mysql_close();
  38. if (isset($_POST['login']) && isset($_POST['pwd']))
  39. {
  40. if (isset($pwd) && isset($pwd_valide) && $pwd == $pwd_valide)
  41. {
  42. $_SESSION['login'] = $_POST['login'];
  43. $_SESSION['pwd'] = $_POST['pwd'];
  44. $_SESSION['accessvar']= 'true';
  45. $_SESSION['utilnum']=$id;
  46. $_SESSION['utilnom']=$nom;
  47. ?><script type="text/javascript">
  48. document.location.replace("?menupropal" );
  49. </script>
  50. <?
  51.  }
  52.  else {echo $errLogin;
  53.  }
  54.  }
  55.  }
  56. ?>
  57. <form name="form" action="?login" method="post">
  58. <fieldset>
  59. <label>Votre login :</label><input type="hidden" name="send" value="1">
  60. <input type="text" name="login"><SCRIPT>document.form.login.focus();</SCRIPT><br />
  61. <label>Votre mot de passe :</label><input type="password" name="pwd"><br />
  62. </fieldset>
  63. <fieldset>
  64. <p align="center"><input name="submit" type="submit" value="Connexion"></p>
  65. </fieldset>
  66. </form>

Reply

Marsh Posté le 19-05-2006 à 12:11:38   

Reply

Marsh Posté le 19-05-2006 à 12:16:19    

tu chiffre les mots de passe de ta base, puis tu les compares au mot de passe de l'utilisateur, que tu aura chiffre.
 

Code :
  1. if($mot_de_passe_base_donnees == sha1($mot_de_passe_utilisateur)) {
  2. // tout roule
  3. }


http://uk2.php.net/manual/en/function.sha1.php
http://uk2.php.net/manual/en/function.md5.php


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 19-05-2006 à 12:50:48    

Avant de te preocuper de tes mdp en base de donnee, tu devrais plutot faire un filtrage des valeurs que tu utilises pour ta requete ($login = $_POST['login']; ). Va faire un tour sur la doc php et cherche 'mysql_real_escape_string'.
 
Sinon 2-3 trucs en passant:
 
- Pour tester la methode sur ta page, utilise '$_SERVER['REQUEST_METHOD']' plutot qu'un champ cache ('send')
- Pour faire des redirections, utilise php (header()) plutot que js
- Tu utilises des valeurs dans ta requete et tu testes leurs existance (isset()) apres les avoir utilisees  
- ...
 
Sinon pour eviter de stocker les mdp en clair, zapan666 a tout dit.


Message édité par Woutcha le 19-05-2006 à 14:51:51
Reply

Marsh Posté le 19-05-2006 à 15:37:11    

un petit ajout à ce qu'a dit zapan666.
Pour sécuriser un peu plus les mdp dans ta base, tu peux rajouter un "grain de sel" à ton mdp :  
http://matthieu.developpez.com/authentification/#L2.2
 
Ceci permet de se prémunir contre les dictionnaires.

Reply

Marsh Posté le 20-05-2006 à 14:08:20    

Merci à tous, je vais regarder toutes ces solutions, je vous tiens au courant de mon avancement...

Reply

Marsh Posté le 20-05-2006 à 21:52:02    

Salut,
je n'ai pas très bien compris le principe du "grain de sel", je vois bien comment "brouiller" le hash du mdp mais comment ensuite vérifier qu'un mot de passe saisi par un utilisateur est correcte?
 
Y-a-t-il plus de doc à ce sujet quelque part sur Internet?
Je demande, parce qu'il est difficil de trouver de la doc avec google en n'ayant que les termes "grain de sel" comme point de départ. Merci d'avance!

Reply

Marsh Posté le 21-05-2006 à 01:58:08    

dwogsi a écrit :

Salut,
je n'ai pas très bien compris le principe du "grain de sel", je vois bien comment "brouiller" le hash du mdp mais comment ensuite vérifier qu'un mot de passe saisi par un utilisateur est correcte?


 
Comme le grain de sel est stocké en clair dans la db, c'est pas vraiment un problème, il suffit de le récupérer et de le coller au mot de passe proposé puis de faire le hash et de le comparer avec le hash dans la db (tout ça en une fois normalement), genre

Code :
  1. select id from membres where login='$nom' and pass=md5($mdp+grain_sel)

Reply

Marsh Posté le 21-05-2006 à 08:28:10    

naceroth a écrit :

Comme le grain de sel est stocké en clair dans la db, c'est pas vraiment un problème, il suffit de le récupérer et de le coller au mot de passe proposé puis de faire le hash et de le comparer avec le hash dans la db (tout ça en une fois normalement), genre

Code :
  1. select id from membres where login='$nom' and pass=md5($mdp+grain_sel)



sql injection [:dawak]

Reply

Marsh Posté le 21-05-2006 à 15:51:57    

Ok je vois, donc en fait on stock une infos en plus par personne, un nombre.

Reply

Marsh Posté le 21-05-2006 à 15:53:12    

nan tu le stocke pas, il est en dur quelque part dans un fichier en tant que variable
 
et c'est le MD5 du MDP qui est stocké ;)
 
dis donc dwogsi tu me décois là :o

Reply

Marsh Posté le 21-05-2006 à 15:53:12   

Reply

Marsh Posté le 21-05-2006 à 15:54:38    

lol ba désolé mais cette histoire de grain de sel me perturbe et j'ai pas les idée très claires aujourd'hui (histoire d'alcool et de samedi soir...). Désolé.

Reply

Marsh Posté le 21-05-2006 à 16:00:13    

gatsu35 a écrit :

nan tu le stocke pas, il est en dur quelque part dans un fichier en tant que variable


 
Oui, bien sûr, tout le monde avec le même, c'est sûr que ça va compliquer la création des dictionnaires. Pas du tout en fait, le grain de sel est bien stocké dans la db, quel intérêt de vouloir "sécuriser" un mdp en lui ajoutant une valeur fixe, tu m'expliques ?

Reply

Marsh Posté le 21-05-2006 à 16:02:34    

ouai mais en même temps si quelqu'un peut se procurer les hash des mdp, ils doit bien pouvoir se procurer aussi se qui se trouve à côté, le grain de sel entre autres. Alors le mieux serait à mon gout de ne pas le stocker dans la db!

Reply

Marsh Posté le 21-05-2006 à 16:10:41    

L'idée n'est pas tant de le rendre impossible que de le rendre difficile à mettre en oeuvre.
 
En partant du principe que tu connais le hash et le gds, tu peux créer le dico. Avec la solution du gds unique : 1 dico = tous les mdp vulnérables dans ta base. Avec l'autre : 1 dico nécessaire par mdp. Lequel te semble le plus sûr ?

Reply

Marsh Posté le 21-05-2006 à 16:15:30    

Il est vrai que ça rend les choses bien plus complexes.
Le mieux serait encore de stocker le grain de sel ailleur que dans la DB.

Reply

Marsh Posté le 21-05-2006 à 16:16:27    

naceroth a écrit :

Oui, bien sûr, tout le monde avec le même, c'est sûr que ça va compliquer la création des dictionnaires. Pas du tout en fait, le grain de sel est bien stocké dans la db, quel intérêt de vouloir "sécuriser" un mdp en lui ajoutant une valeur fixe, tu m'expliques ?


 
 
Imagine que parmis les gens qui ont créé un compte sur ton site, yen a un assez débile pour utiliser le mot de passe "chien"
 
ben c'est assez facile de le cracker avec un dictionnaire non ?
 
donc la méthode consiste à lui rajouter une bien belle phrase toute pourrave :  
"chien"+"%^('(fsz" = chien%^('(fsz
et tu fais le MD5 de ça
et là tu peux être sur que le dictionnaire l'aura dans le cul :o
 

Reply

Marsh Posté le 21-05-2006 à 16:25:03    

gatsu35 a écrit :

Imagine que parmis les gens qui ont créé un compte sur ton site, yen a un assez débile pour utiliser le mot de passe "chien"
 
ben c'est assez facile de le cracker avec un dictionnaire non ?


 
Ou comment répondre à côté de la question. Ma question ne concernait pas l'intérêt du gds (que j'ai détaillé à Dwogsi après le post de Djebel1) mais de celui d'un gds unique. Parce que tu as beau dire, si on peut cracker facilement chien avec un dico, on peut aussi cracker facilement chien%^('(fsz. Et sur de multiples mdp "protégés" en déduire que ton gds vaut %^('(fsz, ce qui ne rend pas vraiment ton mdp plus sûr. :)

Reply

Marsh Posté le 21-05-2006 à 17:16:24    

naceroth a écrit :

Oui, bien sûr, tout le monde avec le même, c'est sûr que ça va compliquer la création des dictionnaires. Pas du tout en fait, le grain de sel est bien stocké dans la db, quel intérêt de vouloir "sécuriser" un mdp en lui ajoutant une valeur fixe, tu m'expliques ?


 
Je confirme, le gds est stocke dans la DB et il faut generer 1 gds par utilisateur, sinon ca n'a aucun sens/interet...

Reply

Marsh Posté le 21-05-2006 à 17:19:57    

>Le mieux serait encore de stocker le grain de sel ailleur que dans la DB
 
non mais le grain de sel tu pourrais l'afficher à côté du nom de chaque utilisateur ça serait pas un pbl :  
- la constitution d'un dictionnaire est fastidieuse et longue, et est forcément faite bien avant une attaque
- Pour cracker les mdp de votre base, le hacker devra constitué un dictionnaire pour chaque utilisateur, ce qui est complètement inenvisageable actuellement
- stockez le en clair dans la bdd. Le grain de sel n'a pas besoin d'être crypté (et ne doit pas l'être). Le hacker peut le connaitre, ça l'empechera pas de devoir se créer un dictionnaire.


Message édité par Djebel1 le 21-05-2006 à 18:57:54
Reply

Marsh Posté le 22-05-2006 à 11:03:20    

Bonjour,
J'ai réussi à crypter mes mots de passe... Ca fonctionne impéccable, et je vais regarder les autres remarques que vous m'avez fait. En revanche je vois pas où mettre le mysql_escape_string.

Code :
  1. $requete = "select * from `te_utilisateur` where `utillog`='mysql_escape_string($login)";


Mais ça marche pas... Peut être que j'ai pas compris l'utilisation de la fonction.

Reply

Marsh Posté le 22-05-2006 à 11:10:29    

[:pingouino]
Tu ne peux pas lancer une fonction, pouf, comme ca, dans une chaine de catactere. C'est pas la fete non plus hein  :D  

Code :
  1. $login_sql = mysql_escape_string($login);
  2. $requete = "select * from `te_utilisateur` where `utillog`='".$login_sql."'";


Message édité par zapan666 le 22-05-2006 à 11:11:12

---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 22-05-2006 à 11:12:25    

où est la sécurité puisque le mot de passe est envoyé en clair du client au serveur, puis haché ?

Reply

Marsh Posté le 22-05-2006 à 15:26:50    

jagstang a écrit :

où est la sécurité puisque le mot de passe est envoyé en clair du client au serveur, puis haché ?


 
Hasher le mot de passe pour le stocker dans la base de donnee ne repond pas au problem de securite que tu evoques (une personne qui "sniff" le reseau intercepte le mot de pass lors de son envoie au serveur).
 
La technique de hashage permet juste d'eviter que si quelqu'un arrive a acceder a la base de donnee, il ne puisse voir les mots de passe de tous les utilisateurs en clair (technique pouvant etre amelioree par l'utilisation d'un "gds" ou "salt" en anglais).
 
Pour repondre au pb que tu evoques, le plus simple est sans doute de mettre en place une connexion en SSL.


Message édité par Woutcha le 22-05-2006 à 15:27:31
Reply

Marsh Posté le 23-05-2006 à 09:57:35    

Je précise que tout est crypté en 128 bits... Le serveur n'accepte que les connections en SSL....

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed