Aller au contenu principal


Drupal - perte de mot de passe

Dans Drupal  le mot de passe n'apparait pas en clair dans la base de données. Depuis la V8, c'est le résultat d'une fonction de hachage qui apparait. Il n'est donc pas possible de trouver un mot de passe perdu  en consultant la base de données.

Billet créé le :
16 Mar 2022

Pour résoudre ce problème, on ne peut  que remplacer ce "hachage" par le hachage d'un nouveau mot de passe (par exemple "123456") par la fonction de hachage que Drupal utilise. Malheureusement, cette fonction de hachage utilise un paramètre (le sel ou salt) qui est définit de manière aléatoire à chaque création d'un mot de passe. En savoir plus sur le salage d'un mot de passe.

Ce billet décrit une solution pour résoudre ce problème.

La procédure décrite ci-après ne permet pas de retrouver un mot de passe perdu (cela est impossible). Elle permet uniquement de le remplacer.

C'est en suivant les10 étapes ci-dessous que je solutionne le problème de la perte de mot de passe d'un utilisateur que je nomme "Jai.Perdu" pour simplifier l'exposé..

Copier le contenu de l'onglet "crypt2.php" du bas de la page et coller le dans un éditeur type "notepad++" ;
 

Enregistrer ( par exemple à la racine de votre disque dur sous le nom  crypt2.php) ;
 

Copier  la donnée du champ "pass" rendu de  la requête 
SELECT `uid`,` pass` FROM `users_field_data` WHERE `name` LIKE "%Jai.Perdu%" 
en effet, le hachage du mot de passe perdu figure dans le champ "pass" de l'utilisateur "Jai.Perdu" de la table "users_field_data" dans la base de données Drupal.
Noter la donnée du champ "uid" (36 dans l'exemple illustré) qui sera utilisé dans l'étape 10.
 Cliquer pour agrandir l'image

Coller le comme valeur de la variable "$hash_mdp_perdu" du fichier "crypt2.php" ;
 

Taper le nouveau mot de passe comme valeur de la variable "$new_password" sauf si la valeur par défaut "123456" vous convient ;
 

Enregistrer le fichier et copier le par exemple à la racine de votre site web de développement ;
 

Lancer votre navigateur web ( Firefox par exemple) ;
 

Taper l'adresse qui vous permet d'atteindre cette page, par exemple : http://localhost/crypt2.php ;
 Cliquer pour agrandir l'image

La page affiche la donnée (dans l' exemple : "$S$ERjU6hF9cDax0/n/a4l/k7CD5ODNDrgiPUcd1sqIb9Qdw/2VqsIo") qu'il vous faut placer dans le champ "pass" de l'utilisateur "Jai.Perdu" dans la table "users_field_data" par la requête
UPDATE `users_field_data` SET `pass` = ''$S$ERjU6hF9cDax0/n/a4l/k7CD5ODNDrgiPUcd1sqIb9Qdw/2VqsIo" WHERE `name` = "Jai.Perdu"
 

Enfin effectuer cette dernière requête :
DELETE FROM cache_entity WHERE cid like '%36%' 
ou 36 est l'uid de l'utilisateur 'Jai.perdu" qui a été noté à l'étape 4.
ou (plus grossier) vider la totalité des caches en cliquant sur le bouton  "effacer tous les caches" dans le menu d'administration "configuration - performance ".
 

une variante est disponible en cliquant ici

Une autre manière de procéder pour créer un mot de passe haché  s'appuie sur le script "password-hash.sh" disponible dans "core/scripts" d'une installation de drupal et  que l'on exécutera en mode commande avec drush :
drush php-script password-hash.sh -- 123456 exécuté depuis le dossier "core/scripts" de votre installation.
pour créer un hachage pour le mot de passe 123456.

L'utilisateur "Jai.Perdu" pourra se loger en utilisant son  identifiant habituel (Jai.Perdu) et le mot de passe utilisé à la ligne 5 ci-dessus ("123456" par défaut).

 

Cliquez sur le bouton pour copier le code
dans le presse papier
    
<?php
/* moncrypt('sha512',"nouveau mot de passe","hash du mot de passe perdu")
*  adaptation de \htdocs\core\lib\Drupal\Core\Password\PhpassHashedPassword.php
*/
$ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

//récupérer le hash du mdp perdu dans la table "users_field_data" champ "pass"
$hash_mdp_perdu = '$S$ERjU6hF9cR3vhlq437kEZAGGVizq7RyiGyZ4UIgd9upLkkT9W4Ve';

// taper le nouveau mot de passe
$new_password = "123456";
echo moncrypt('sha512', $new_password, $hash_mdp_perdu);

function base64Encode($input, $count) {
    global $ITOA64;
    $output = '';
    $i = 0;
    do {
      $value = ord($input[$i++]);
      $output .= $ITOA64[$value & 0x3f];
      if ($i < $count) {
        $value |= ord($input[$i]) << 8;
      }
      $output .= $ITOA64[($value >> 6) & 0x3f];
      if ($i++ >= $count) {
        break;
      }
      if ($i < $count) {
        $value |= ord($input[$i]) << 16;
      }
      $output .= $ITOA64[($value >> 12) & 0x3f];

      if ($i++ >= $count) {
        break;
      }
      $output .= $ITOA64[($value >> 18) & 0x3f];
    } while ($i < $count);

    return $output;
  }

function getCountLog2($setting) {
    global $ITOA64;
    return strpos($ITOA64, $setting[3]);
  }
function moncrypt($algo, $password, $setting) {

    $setting = substr($setting, 0, 12);

    if ($setting[0] != '$' || $setting[2] != '$') {
      return FALSE;
    }
    $count_log2 = getCountLog2($setting);
    $salt = substr($setting, 4, 8);
    $count = 1 << $count_log2;

    $hash = hash($algo, $salt . $password, TRUE);
    do {
      $hash = hash($algo, $hash . $password, TRUE);
    } while (--$count);

    $len = strlen($hash);
    $output = $setting . base64Encode($hash, $len);

    $expected = 12 + ceil((8 * $len) / 6);
    return (strlen($output) == $expected) ? substr($output, 0, 55) : FALSE;
  }
?>