Mysql
 sql >> Base de données >  >> RDS >> Mysql

PHP et MySQL comparent le mot de passe

Je vois que vous stockez un hachage du mot de passe dans la base de données, mais pour le bénéfice des autres lecteurs, jamais stocker les mots de passe en texte brut dans la base de données. Vous ne voulez pas être comme Monster.com.uk !

Vous devez utiliser une fonction de hachage plus puissante que MD5() . Idéalement, vous devriez utiliser SHA256. Cette méthode de hachage est disponible en PHP en utilisant le hash() fonction.

Vous devez également appliquer un salt aléatoire au mot de passe. Stockez une valeur de sel différente pour le compte de chaque utilisateur. Cela aide à vaincre les attaques par dictionnaire et table arc-en-ciel attaques.

Vous devriez apprendre à utiliser mysqli extension au lieu de l'ancienne extension mysql. Mysqli prend en charge les requêtes paramétrées, ce qui vous permet de réduire la vulnérabilité à certaines attaques par injection SQL.

Voici un exemple de code. Je ne l'ai pas testé, mais ça devrait être assez proche de fonctionner :

$input_login = $_POST['login'];
$input_password = $_POST['password'];

$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);

while ($stmt->fetch()) {
  $input_password_hash = hash('sha256', $input_password . $salt);
  if ($input_password_hash == $password_hash) {
    return true;
  }
  // You may want to log failed password attempts here,
  // for security auditing or to lock an account with
  // too many attempts within a short time.
}
$stmt->close();

// No rows matched $input_login, or else password did not match
return false;

D'autres personnes suggèrent que la requête devrait tester login = ? AND password = ? mais je n'aime pas faire ça. Si vous faites cela, vous ne pouvez pas savoir si la recherche a échoué parce que la connexion n'existait pas ou parce que l'utilisateur a fourni un mauvais mot de passe.

Bien sûr, vous ne devez pas révéler à l'utilisateur la cause de l'échec de la tentative de connexion, mais vous peut avoir besoin de savoir, afin que vous puissiez consigner toute activité suspecte.

@Javier dit dans sa réponse que vous ne devriez pas récupérer le mot de passe (ou le hachage du mot de passe dans ce cas) de la base de données. Je ne suis pas d'accord.

Javier montre l'appel de md5() dans le code PHP et en envoyant la chaîne de hachage résultante à la base de données. Mais cela ne prend pas en charge le salage du mot de passe facilement. Vous devez faire une requête séparée pour récupérer le sel de cet utilisateur avant de pouvoir faire le hachage en PHP.

L'alternative est d'envoyer le texte clair mot de passe sur le réseau depuis votre application PHP vers votre serveur de base de données. Toute personne qui écoute votre réseau peut voir ce mot de passe. Si vous avez des requêtes SQL en cours de journalisation, toute personne ayant accès aux journaux peut voir le mot de passe. Les pirates motivés peuvent même plonger dans les poubelles pour trouver d'anciens supports de sauvegarde du système de fichiers et lire les fichiers journaux de cette façon !

Le moindre risque consiste à récupérer la chaîne de hachage du mot de passe de la base de données dans l'application PHP, à la comparer au hachage de l'entrée de l'utilisateur (également dans le code PHP), puis à supprimer ces variables.