[RESOLU] passer sha1 à password_hash

Eléphant du PHP | 172 Messages

10 mars 2017, 21:53

Bonjour :D

voilà mon problème:

Tout roule avec sha1 mais en modifiant avec password_hash
j'ai bien le hash dans la bdd mais lors de validation le mot de passe n'est pas reconnu?
j'ai mis ancienne ligne et nouvelle pour la compréhension.

Par avance merci
//  $password = mysqli_real_escape_string(sha1($pass)); 
 
    $password = mysqli_real_escape_string(password_hash($pass, PASSWORD_DEFAULT));  
           
    
// $requete = "SELECT * FROM membres WHERE pseudo = '".$pseudo."' AND pass = '".sha1($pass)."'"; 

   $requete = "SELECT * FROM membres WHERE pseudo = '".$pseudo."' AND pass = '". password_hash($pass, PASSWORD_DEFAULT)."'";

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

12 mars 2017, 11:39

salut

c'est normal password_hash est basée sur blowfish et pas sha1, donc les hash ne correspondent pas.

d'ailleurs rien que la longueur peut te mettre la puce à l'oreille
- avec password_hash : 60 caractères
- avec sha1 : 40 caractères

si ta bdd est production c'est un peu foutu, sinon c'est bon ;)

pour nuancer tu peux
- tu peux tenter en récupérant des rainbow tables sh1 mais ce n'est même pas certain
- Forcer tout le monde a changer son mot de passe à la premier connexion. Pour cela ajoute une colonne pour le mot de passe hash avec password_hash. Lors de la connexion si cette colonne n'est pas vide tu utilise password_hash et compare que sur cette colonne. Sinon utilise sha1 pour l'authentification et demande a changer le mot de passe. Lorsque c'est fait n'oublie pas de vider la colonne avec le sha1.

quand tout le monde aura changer son mot de passe tu dégages l'ancienne colonne.

autre solution plus brutale et moins sécurisée (utilisation toute fois sur un intranet ou sur un nombre de compte limité) : si tu as les emails des gens tu leur changes leurs mots de passes par une chaîne aléatoire (différente pour chacun) et tu leurs envois pas email. Si possible il faut qu'a la première connexion il change leurs mot de passe.
cela te permet d'éviter la phase de migration (enfin elle est la le temps du script et d'envoyer les emails c'est pas long).

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 172 Messages

13 mars 2017, 10:25

Bonjour moogli et merci de t'intéresser à mon problème. :D


D'abord je ne fais la modif sur un site en production. En partant du tuto du site phpfrance je veux l'adapter pour mes futurs site s.

avec password_hash

Pour le moment j'ai bien avec :
$password= password_hash($pass, PASSWORD_DEFAULT) ;
le résultat dans la bdd:
$2y$10$DJSoyA3GAxN.mqEcXWTttuDQYUXsVZDChQ3IX1AqFZyDLLt.Zhppy

Maintenant je n'arrive pas à avoir le bon retour pour accces avec:
/* Si $pseudo et $pass différents de null */
    if(isset($pseudo,$pass)) 
    {
         // connexion base
    include("fonctions.php");   /* ma base mes identifiants *
    
         /* Indique à mySql de travailler en UTF-8 (par défaut mySql risque de travailler au standard ISO-8859-1) */
         $conn->query("SET NAMES 'utf8'");
    
         /* Préparation des données pour les requêtes à l'aide de la fonction mysqli_real_escape_string */
         $nom = mysqli_real_escape_string($pseudo);
         $password = mysqli_real_escape_string($pass);
       
         /* Requête pour récupérer les enregistrements répondant à la clause : 
         champ du pseudo et champ du mdp de la table = pseudo et mdp postés dans le formulaire*/
       //  $requete = "SELECT * FROM membres WHERE pseudo = '".$pseudo."' AND pass = '".sha1($pass)."'";    OK sha1
       
       $requete = "SELECT * FROM membres WHERE pseudo = '".$pseudo."' AND pass = '".password_hash($pass, PASSWORD_DEFAULT)."'";     // ne marche pas avec password_hash ?
    
         /* Exécution de la requête */
         $req_exec = $conn->query($requete) or die(mysqli_error());
    
         /* Création du tableau associatif du résultat */
         $resultat = mysqli_fetch_array($req_exec); 

         /* Les valeurs (si elles existent) sont retournées dans le tableau $resultat;  */
         if (isset($resultat['pseudo'],$resultat['pass']))  
               {
                 /* Démarre la session et enregistre le pseudo dans la variable de session $_SESSION['login']
                 qui donne au visiteur la possibilité de visiter les pages protégées.  */
                 session_start();
                 $_SESSION['login'] = $pseudo;
            
                 /* A MODIFIER Remplacer le '#' par l'adresse de votre page de destination, sinon ce lien indique la page actuelle. */
                 $message = '<h4 style="color: green; text-align:center;">Bonjour et bienvenu '.htmlspecialchars($_SESSION['login']).'</h4>  <a href = "page_1.php"><h6 style="text-align:center;">Cliquez ici pour vous connecter</h6></a>';
                }
                else
                {   /* Le pseudo ou le mot de passe sont incorrect */
                $message = 'Le pseudo ou le mot de passe sont incorrect';
                } 

    }
    else 
    {  /* au moins un des deux champs "pseudo" ou "mot de passe" n'a pas été rempli */
    $message = 'Les champs Pseudo et Mot de passe doivent être remplis.';
    }
}

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

13 mars 2017, 12:10

Bonjour,

Il faut que tu utilises la fonction password_verify() pour vérifier que le mdp est le bon car 2 appels simultannés à la fonction password_hash() vont généré des hash différents car avec des salt différents.

http://php.net/password_verify
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 172 Messages

14 mars 2017, 15:35

Bonjour @arthur :D

J'ai bien essayé dans tous les sens mais je n'ai pas pas accès à ma page toujours mot passe invalide. Pourtant mes deux échos me retourne les bonnes valeurs dans invalide?

Merci d'avance pour la solution
if (isset($_POST['pseudo'])) 
{
    $pseudo = (isset($_POST['pseudo']) && trim($_POST['pseudo']) != '')? Verif_magicquotes($_POST['pseudo']) : null;
    $pass = (isset($_POST['pass']) && trim($_POST['pass']) != '')? Verif_magicquotes($_POST['pass']) : null;
    if(isset($pseudo,$pass)) 
    {
  
    include("fonctions.php");    /*connexion base*/
         $conn->query("SET NAMES 'utf8'");
         $nom = mysqli_real_escape_string($pseudo);
         $password = mysqli_real_escape_string($pass);
         $requete = "SELECT * FROM membres WHERE pseudo = '".$pseudo."' AND pass = '".$pass."'"; 
         $req_exec = $conn->query($requete) or die(mysqli_error());
         $resultat = mysqli_fetch_array($req_exec); 
if (password_verify($resultat['pseudo'],$resultat['pass'])) {
    echo '<h1 style="color:green; text-align:center;">Le mot de passe est valide !</h1>';

session_start();
                 $_SESSION['login'] = $pseudo;

                 $message = '<h4 style="color: green; text-align:center;">Bonjour et bienvenu '.htmlspecialchars($_SESSION['login']).'</h4>  <a href = "page_1.php"><h6 style="text-align:center;">Cliquez ici pour vous connecter</h6></a>';
               
} else {
    echo '<h1 style="color:red; text-align:center;">Le mot de passe est invalide.</h1>';
    echo $pseudo ;            // echo OK
    echo '<br>' ;
    echo $pass ;               // echo OK
}
    }
    else 
    { 
    $message = 'Les champs Pseudo et Mot de passe doivent être remplis.';
    }
}
Modifié en dernier par bob56@ le 14 mars 2017, 15:45, modifié 1 fois.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

14 mars 2017, 15:45

salut,

réfléchie un peux à ce que veut dire cette ligne
if (password_verify($resultat['pseudo'],$resultat['pass'])) {

tu compares le pseudo en base et un mot de passe, alors qu'il faut comparer la saisie de l'utilisateur et le mot de passe en base (le hash en fait).

du coup
if(password_verify($_POST['pass'],$resultat['pass'])) devrait plus faire l'affaire.


On ajoute le fait que tu ne dois pas mettre le mot de passe dans le select tu n'auras jamais rien en retour de ta requête tu compares le hash et le mot passe en clair ça ne pas fonctionner ;)
$requete = 'SELECT pass FROM membres WHERE pseudo = \''.$pseudo.'\'';
@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 172 Messages

14 mars 2017, 16:20

merci moogli =D>

J'ai quand même passé de bonnes heures à essayer de comprendre. Tout paraît logique quand on a la solution

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

14 mars 2017, 17:35

:mrgreen: :mrgreen:
Il en faut peu pour être heureux ......