salted hash; login

Fabian Frank

Erfahrenes Mitglied
Hallo,

kurze Frage, kurzer Sinn: Ich habe ein Registrierungsformular, bei dem das Passwort in einen saltedHash umgewandelt wird und in einer Datenbank gespeichert wird.
Wie ist es möglich, beim Login zu prüfen ob das Passwort stimmt?
Mein jetziges Prinzip läuft so ab: Der Benutzer gibt auf der Login-Seite seinen Benutzernamen und das zugehörige Passwort ein; dann wird auf existenz geprüft und so weiter, und zu guter letzt wird das Passwort mit genau dem selben Skript, mit dem der Benutzer, bzw. das Passwort vom Benutzer registriert wurde in den saltedHash wert umgewandelt. Leider zeigt er nun immer an, dass die Login-Daten nicht korrekt sind.
Kann es sein, dass die saltedhash funktion immer einen anderen Hashwert beim selbigen Passwort erzeugt, oder wie lässt sich das fehlverhalten des Skript's erklären?

Hier die Quellcode's:

Kleiner Hinweis am Rande: Das Skript funktioniert tadellos, sobald man alles, was sich um den Hashwert dreht entfernt


loginseite
Code:
<table width="192" border="0" cellpadding="3">
<form name="login-form" method="post" action="./scripts/login.php">
  <tr>
    <td width="186"><span class="title">Benutzer</span><br />
      <input name="log_benutzer" type="text" maxlength="25" class="form-text" size="30" /></td>
  </tr>
  <tr>
    <td><span class="title">Passwort</span><br /><input name="log_passwort" type="password" maxlength="25" class="form-text" size="30" /></td>
  </tr>
  <tr>
    <td><div align="right"><input type="hidden" name="log_real_form" value="on" /><input name="login" type="submit" value="Einloggen" /></div></td>
  </tr>
 </form>
</table>

Logindaten-Check
PHP:
<?
if (!isset($_POST['log_benutzer'], $_POST['log_passwort'], $_POST['log_real_form'])) {
   echo "<font face='arial' size='2'>Fehler #404: Verwendung eines ungültigen Formulars</font>"; 
   exit();
   }
session_start();

if(isset($_POST['log_benutzer']) and trim($_POST['log_benutzer']) != '' and isset($_POST['log_passwort']) and trim($_POST['log_passwort']) != '') {
	if(get_magic_quotes_gpc()) {
		$_POST['log_benutzer'] = stripslashes($_POST['log_benutzer']);
		}
	include "../config/config.php";	/* Verbindungsdaten zur Datenbank (und zugleich Aufbau der Verbindung) */
	$benutzer = mysql_real_escape_string($_POST['log_benutzer']);
	$passwort = $_POST['log_passwort'];
	function saltcrypt($passwort, $salt) { /* Funktion zum erstellen des Hashes */
    	return hash('sha256', $passwort . $salt);
		}
	$code = "4971"; /* Beispielcode (enspricht dem "Salz" des gesalzenen Hashes */
	$salt = $code;
	$saltedpasswort = saltcrypt($passwort, $salt); 
	$dummy = mysql_query("SELECT * FROM `login_data` WHERE `Benutzer` = '".$benutzer."' AND `Passwort` = '".$saltedpasswort."'"); 
	if(mysql_num_rows($dummy) > 0) {
	
		/* Falls die Daten richtig sein sollten.... */
		
		$fetch = mysql_fetch_object($dummy);
		$id = $fetch->user_id;
		
		header ("Location: main.php");
		exit();
		}
	else {
		$_SESSION['login_error'] = "false"; /* dient der Fehlerausgabe auf der FOrmularseite */
		header ("Location: ../index.php");
		exit();
		}
	}
else {
	$_SESSION['login_error'] = "empty"; /* dient der Fehlerausgabe auf der FOrmularseite */
	header ("Location: ../index.php");
	exit();
	}
?>

Bei dem $code = "4971" handelt es sich momentan nur als Darstellungszweck um einen konstanten code, dies würde später durch einen zufallsgenerierten Code, der in der Zeile des Benutzers in der DB mitgespeichert werden würde ersetzt.


Ich danke schonmal für eure Mühe,

Viele Grüße,

Fabi
 
Zuletzt bearbeitet:
Lass dir $saltedpasswort doch einmal zu Testzwecken ausgeben und vergleiche es mit dem Wert in der Datenbank.
 
Du musst denselben Salt-Wert wie bei der Registrierung verwenden, um die Identität beider Werte prüfen zu können. Dazu speicherst du am besten den Salt-Wert direkt zusammen mit dem Hash-Wert.
 
Hi,
dieser Teil kommt mir seltsam vor:
PHP:
$passwort = $_POST['reg_passwort'];

Ich sehe nicht wo das "reg_passwort" herkommt. Ich glaube da sollte auch "log_passwort" stehen. Denn so dürfte nachher in Passwort eine leere Zeichenkette stehen.

mfg.Fide
 
Lass dir $saltedpasswort doch einmal zu Testzwecken ausgeben und vergleiche es mit dem Wert in der Datenbank.
Alles klar; ist nur bisschen blöd. Ich hab einfach nochmal einen Benutzer registriert (mit dem selben PW) und dann direkt die zeilen in der Datenbank verglichen: Und sie waren identisch.


Du musst denselben Salt-Wert wie bei der Registrierung verwenden, um die Identität beider Werte prüfen zu können. Dazu speicherst du am besten den Salt-Wert direkt zusammen mit dem Hash-Wert.
Ganz klar, es ist auch der selbe Wert. Hab mich nur falsch ausgedrückt: Dieser Wert soll (irgendwann) einmal durch einen zufallsgenerierten Code ersetzt werden, dann muss ich natürlich auch den Code bei der Registrierung abspeichern und beim Login auslesen.
Ich möchte das alles jedoch in Etappen realisieren; damit beschäftige ich mich dann, wenn das Script soweit funktioniert.

Hi,
dieser Teil kommt mir seltsam vor:
PHP:
$passwort = $_POST['reg_passwort'];

Ich sehe nicht wo das "reg_passwort" herkommt. Ich glaube da sollte auch "log_passwort" stehen. Denn so dürfte nachher in Passwort eine leere Zeichenkette stehen.

mfg.Fide
danke, Hast vollkommen recht, doch die Zeile ist eh überflüssig, da es ja weiter oben schon deklariert ist. Trotzdem hätte sie für einen Fehler gesorgt, wie du gesagt hast; funktionieren tut es trotzdem nicht... (In meinem Starter-Post ausgebessert...)
 
Zuletzt bearbeitet:
so, Leute, das Rätsel hat sich gelöst.

Mir ist ein total dummer Fehler unterlaufen; habe in der Datenbank das Feld vom Passwort auf 64 Zeichen begrenzt; der Hash-Wert hatte jedoch etwas mehr...

Also, danke an euch nochmal.

Ciao
 
So eine starke Hash-Funktion brauchst du gar nicht. SHA-1 reicht da eigentlich völlig aus, erspart dir dann auch Speicherplatz, da du dort eigentlich nur eine20 Zeichen langes Feld benötigst.
 
Zurück