6 Stimmen

PHP & MySQL Passwort vergleichen

Wie kann man überprüfen, ob ein Benutzer das richtige Kennwort eingegeben hat, um sich anzumelden?

Das ist es, was ich (aus einer Reihe von Kombinationen...) mache:

<?

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

mysql_connect('localhost', 'root', 'abc123');

mysql_select_db('aun_vox') or die(mysql_error());

$q = mysql_query("SELECT password FROM customer WHERE login='$login'");
$db_pass = mysql_result($q, 0);

if(md5($password) == $db_pass)
{
    echo "You did it.";
}

else echo "Wrong.";

?>

Wie ich aus der Ausgabe ersehen kann, stimmt etwas nicht mit der mysql_result aber ich weiß nicht, wie ich das machen soll.

Kann mir bitte jemand helfen?

3 Stimmen

Wir hier bei stackoverflow beantworten keine Fragen zu Logins. Wir ziehen es vor, in großen technischen Details zu erklären, wie man Benutzereingaben säubert. Es ist besser, sicher zu sein, als eine funktionierende Website zu haben.

5 Stimmen

@Grant: Du machst Witze, oder?

0 Stimmen

Bitte beachten Sie, dass die Antworten auf dieser Seite veraltet und daher unsicher sind. Frage stattdessen.

18voto

Bill Karwin Punkte 493880

Wie ich sehe, speichern Sie einen Hash des Kennworts in der Datenbank, aber nur zum Nutzen anderer Leser, niemals Passwörter im Klartext in der Datenbank speichern. Sie wollen nicht, dass wie Monster.com.uk !

Sie sollten eine stärkere Hash-Funktion verwenden als MD5() . Idealerweise sollten Sie SHA256 verwenden. Diese Hash-Methode ist in PHP mit dem Befehl hash() Funktion.

Sie sollten auch eine zufällige Salz zum Passwort. Speichern Sie für jedes Benutzerkonto einen anderen Salt-Wert. Dies hilft bei der Abwehr von Wörterbuchangriffen und Regenbogentisch Angriffe.

Sie sollten lernen, die mysqli Erweiterung anstelle der alten mysql-Erweiterung. Mysqli unterstützt parametrisierte Abfragen, so dass Sie die Anfälligkeit für einige SQL-Injection-Angriffe verringern können.

Hier ist ein Beispielcode. Ich habe es nicht getestet, aber es sollte ziemlich nahe an der Arbeit sein:

$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;

Andere Leute schlagen vor, die Abfrage sollte auf login = ? AND password = ? aber das tue ich nicht gerne. Wenn Sie dies tun, können Sie nicht wissen, ob die Suche fehlgeschlagen ist, weil die Anmeldung nicht existiert oder weil der Benutzer ein falsches Passwort angegeben hat.

Natürlich sollten Sie dem Benutzer nicht verraten, wodurch der fehlgeschlagene Anmeldeversuch verursacht wurde, aber Sie wissen müssen, damit Sie verdächtige Aktivitäten protokollieren können.


@Javier sagt in seiner Antwort, dass Sie das Kennwort (oder den Kennwort-Hash in diesem Fall) nicht aus der Datenbank abrufen sollten. Dem stimme ich nicht zu.

Javier ruft an md5() in PHP-Code und sendet die daraus resultierende Hash-Zeichenkette an die Datenbank. Dies unterstützt jedoch nicht das einfache Salzen des Passworts. Sie müssen eine separate Abfrage durchführen, um den Salt dieses Benutzers abzurufen, bevor Sie den Hash in PHP durchführen können.

Die Alternative ist das Senden der Klartext Passwort über das Netzwerk von Ihrer PHP-Anwendung zu Ihrem Datenbankserver. Jeder, der Ihr Netzwerk abhört, kann dieses Passwort sehen. Wenn Sie SQL-Abfragen protokollieren lassen, kann jeder, der Zugang zu den Protokollen erhält, das Kennwort sehen. Motivierte Hacker können sogar nach alten Dateisystem-Backup-Medien tauchen und auf diese Weise die Protokolldateien lesen!

Das geringere Risiko besteht darin, die Hash-Zeichenkette des Kennworts aus der Datenbank in die PHP-Anwendung zu holen, sie mit dem Hash-Wert der Benutzereingabe zu vergleichen (ebenfalls im PHP-Code) und diese Variablen dann zu verwerfen.

0 Stimmen

In Ihrem Code fehlte nur eine Sache. mysqli_prepare() benötigt zwei Parameter - der erste ist das Ergebnis der Anweisung mysqli_connect(). Da ich stattdessen mysql_connect() verwendet habe, hat es nicht funktioniert. Aber nach der Änderung funktioniert es gut. Vielen Dank für Ihre Hilfe.

0 Stimmen

Danke für den Hinweis, ich habe das Problem behoben. Ich habe allerdings nicht gezeigt, wie man sich mit der Datenbank verbindet. Ich bin einfach davon ausgegangen, dass Sie ein Live $mysqli Objekt haben.

0 Stimmen

Mysqli ist zu schrecklich fehlerhaft, um es zu benutzen (leider)

3voto

BrynJ Punkte 8034

Erstens, stellen Sie sicher, dass Sie Ihre Variablen richtig entschlüsseln, bevor Sie sie in der Abfrage verwenden - benutzen Sie mysql_real_escape_string().

Warum verwenden Sie dann nicht die MD5-Funktion von MySQL, um in Ihrer Abfrage nach einem gültigen Login zu suchen?

SELECT login FROM customer WHERE login='$login' AND password = MD5('$password')

Dann verwenden Sie mysql_num_rows(), um die Anzahl der zurückgegebenen Zeilen zu zählen.

1voto

Javier Punkte 58737

Einige Punkte:

  • Fügen Sie KEINE Zeichenkettendaten in die Abfragezeichenfolge ein. Vor allem keine benutzerdefinierten Daten. Was würde passieren, wenn ich mich mit "Robert' ;drop table customer" anmelde? Verwenden Sie entweder die Escape-Routinen oder (viel besser) vorbereitete Anweisungen und Bindungsparameter.
  • Speichern Sie KEINE Klartext-Passwörter in Ihrer Datenbank. (das ist in Ordnung für Sie)
  • Rufen Sie KEINE Kennwörter aus Ihrer Datenbank ab.

Normalerweise mache ich so etwas wie:

$q = preparestatement ("SELECT id FROM customer WHERE login=? AND password=?");
bindvalue ($q, $_POST['login']);
bindvalue ($q, md5($_POST['password']));
$id = execprepared ($q);

if($id) {
    echo "You did it.";
} else {
    echo "Wrong.";
}

1 Stimmen

Wir nennen ihn den kleinen Bobby Tables.

3 Stimmen

Sie sollten vielleicht darauf hinweisen, dass Sie hier keinen nativen PHP-Code verwenden. bindvalue() hat mich ein wenig verwirrt, und das umso mehr, als ich es auf php.net nicht finden konnte. Schließlich fand ich online PHP Data Objects (PDO), das die Informationen in Ihrem Beispiel abdeckt.

0voto

Uday Hiwarale Punkte 3748

Holen Sie sich das Passwort des Benutzers aus der FORM POST-Methode und konvertieren Sie $_POST['password'] //aus dem Formular// in ein geeignetes Format in php/jsp/irgendeinem anderen und vergleichen Sie es dann mit dem formatierten Passwort in Ihrer Datenbank

Im Allgemeinen wird die md5-Verschlüsselung verwendet, wenn Sie md45('{$_POST['password']}')= in Ihrer Datenbank vergleichen können; oder in der Regel mysql verwenden password('Ihr Passwort') Befehl bei der Erstellung von Passwort daher zunächst Konzert Ihre $_POST['password'] in mysqli_query und mysqli_fetch_array zu erhalten verschlüsselten Passwort-Wert und dann vergleichen.

0voto

PodTech.io Punkte 4316

Ab PHP 5.6 können Sie die Funktion hash_compare verwenden.

 $users_password = hash(sha256,$salt.$post_password);

 if (hash_equals($users_dbpassword, $users_password)) {
      //pass is good
 } else {
       // pass failed
 }

http://php.net/manual/ru/function.hash-equals.php

1 Stimmen

Eigentlich sollte diese Funktion nicht verwendet werden, um Passwort-Hashes zu vergleichen (vergleichbare Hashes sind nicht für Passwörter geeignet), verwenden Sie stattdessen passwort_bestätigen() und erzeugen den Hash mit passwort_hash() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X