MD5 Passwort Hashes mit Salt

Aus VMS1 Tutorial

Wechseln zu: Navigation, Suche

Um die Sicherheit der gespeicherten Passwörter zu erhöhen, sollte man diese entweder mit einem zufälligen Salt erweitern, oder auf einen der SHA-2 Algorithmen wechseln.

Da sich das Wechseln des Algorithmus schwieriger gestaltet, gerade im laufenden Betrieb einer Seite, als das nachträgliche Hinzufügen eines Salts, soll dies hier als kleine Umbauanleitung erklärt werden.


Inhaltsverzeichnis

Vorteile

Durch das Hinzufügen eines zufälligen Salt an das eigentliche Passwort erhöht man die Sicherheit des Passwort Hashes, sollte ein Angreifer in den Besitz dieses Hashes gelangen. Einerseits werden dadurch auch kurze Passwörter automatisch länger, da man X Zeichen hinten anhängt, wodurch die Verwendung von Rainbow-Tables und auch Brute-Force Angriffe schwieriger werden, andereseits ist auch bei gleichem Passwort zweier Benutzer der Hash dennoch ein anderer, sofern der Salt nicht der gleiche ist (daher die Zufallsfunktion beim Salt).

Was ein Salt nicht macht

Diese Methode macht nicht das Passwort an sich sicherer, also sollte dieses weiterhin aus möglichst vielen Zahlen, grossen und kleinen Buchstaben wie auch optimalerweise Sonderzeichen bestehen, regelmäßig geändert werden und immer nur auf einer Seite verwendet werden.

Nachteile

Die Funktion im Adminforce, User mit gleichen Passwörtern aufzulisten, funktioniert nach der Änderung nicht mehr.

Einbau

Zuerst wird in der Datenbank eine neue Spalte für den Salt benötigt:

ALTER TABLE `vms_kontodaten` ADD `pwsalt` VARCHAR(10) NOT NULL DEFAULT '' AFTER `passwort`;

Als nächstes muss man sicherstellen, dass sich die User auch mit den "neuen" Passwörtern einloggen können, dazu muss in der Datei lib/session.lib.php an 2 Stellen der Code geändert werden:

$login_check = db_query("SELECT k.uid,k.passwort,k.status,k.hinweis FROM 
                                        ".$db_prefix."_userdaten u
                                        LEFT JOIN ".$db_prefix."_kontodaten k ON k.uid=u.uid
WHERE u.nickname='".$_POST['nickname']."' AND k.passwort=MD5(CONCAT('".$_POST['passwort']."',k.pwsalt)) LIMIT 1");

Sollte der User noch keinen Wert in der Spalte pwsalt haben, wird weiterhin einfach nur das eingegebene Passwort verwendet und daraus der MD5 Hash berechnet. Hat der Benutzer dort allerdings einen Wert, wird dieser an das eingegebene Passwort angehängt.

// Wenn beim User alles O.K. ist!
<|>if|> ($login_check['status'] == 1) {
  db_query("UPDATE ".$db_prefix."_kontodaten SET login_ip='".$ip."' , 
    loginzeit='".<|>time|>()."' 
    WHERE uid=".$login_check['uid']." and passwort=MD5(CONCAT('".$_POST['passwort']."',pwsalt)) LIMIT 1");

Dieser Query muss angepasst werden, damit das Eintragen der IP und Login Zeit funktioniert.

Nun muss noch an 3 Stellen, an denen ein Passwort angelegt bzw. geändert wird, ein Salt generiert werden:

content/konto/userprofil.php:

<|>if|> ($_POST['aendern'] == 'Jetzt ändern!') {
  // Passwort ändern beginn!
  <|>if|> ($_POST['pwd'] && $_POST['pwd2']) {
    <|>if|> ($_POST['pwd'] == $_POST['pwd2']) {
      <|>if|> (<|>strlen|>($_POST['pwd']) >= 8) {
	$pwsalt = create_code(10); //neu
	db_query("UPDATE ".$db_prefix."_kontodaten SET passwort = MD5('".$_POST['pwd'].$pwsalt."'), 
                  pwsalt = '".$pwsalt."' WHERE uid=".$_SESSION['uid'].""); //angepasst

content/intern/anmelden.php:

<|>if|> ($_POST['newsletter'] == 1 and $_POST['paidmails'] == 1) $mailstatus = 3;
$pwsalt = create_code(10); //neu
db_query("INSERT INTO ".$db_prefix."_kontodaten (uid,passwort,pwsalt,status,hinweis,kontostand,login_ip) 
          VALUES ('".$_POST['uid']."',MD5('".$_POST['passwort_1'].$pwsalt."'),
          '".$pwsalt."','0','','0','".$ip."')"); //angepasst
db_query("INSERT INTO ".$db_prefix."_emaildaten (uid,emailadresse,freigabe_fuer) 
          VALUES ('".$_POST['uid']."','".$_POST['emailadresse']."','".$mailstatus."')")

content/intern/daten.php:

<|>if|> ($daten_anfordern['emailadresse']) {
  $neues_passwort = create_code(8);
  $pwsalt = create_code(10); //neu
  db_query ("UPDATE ".$db_prefix."_kontodaten SET passwort=MD5('".$neues_passwort.$pwsalt."'), 
             salt='".$pwsalt."' WHERE uid=".$daten_anfordern['uid'].""); //angepasst

Damit sind die nötigen Änderungen abgeschlossen und jeder User, der sich neu anmeldet, sein Passwort ändert oder sich ein Neues zuschicken lässt, bekommt einen Salt generiert.

Nochmal die Änderungen am SQL Query im Vergleich:

passwort='".md5($_POST['passwort'])."' //alt
passwort=MD5(CONCAT('".$_POST['passwort']."',pwsalt)) //neu

Um zusätzliche Datenbank Anfragen zu vermeiden, wird die MD5 Berechnung an den MySQL Datenbank-Server abgegeben. Das Ergebnis ist dabei das gleiche, es kann aber zu Unterschieden bei der Kodierung der Zeichen kommen, insofern ist ein vorheriger Test mit einem Passwort mit Umlauten etc. sinnvoll.


Link zur HTML Umbau Anleitung: http://www.vms-tutorial.de/dl/Umbau_Passwort_MD5_salt.html

Persönliche Werkzeuge