Zitat von
Delphi-Freak:
Irgendwie ist das aber sinnwidrig.
Zur Verdeutlichung ein Beispiel wie ich es verwende:
1. Auf dem Server sind in der Datenbank *NUR* die MD5-Hashes der Passwörter abgespeichert.
2. Beim Aufruf der Loginseite generiert der Server einen neuen Zufallsschlüssel und merkt ihn sich zusammen mit REMOTE_ADDR und der Uhrzeit in einer speziellen Tabelle. Diesen Zufallsschlüssel nenne ich jetzt mal "Challenge". Er wird auch als verstecktes Feld in das Formular eingebaut.
Code:
<script type="text/javascript" language="JavaScript" src="md5.js"></script>
<script type="text/javascript" language="JavaScript">
<!--
var submitted = false;
function doChallengeResponse() {
password = document.loginform.login_p_field.value;
document.loginform.login_p_field.value = "";
if (submitted) {
alert("Die Daten wurden bereits abgeschickt!");
return false;
} else if (password) {
password = MD5(password);
str = "(" + document.loginform.login_username.value + "|" + password + "|" + document.loginform.login_challenge.value + ")";
document.loginform.login_response.value = MD5(str);
submitted = true;
return true;
} else {
alert("Sie müssen zur Anmeldung ihr Kennwort eingeben");
return false;
}
}
//-->
</script>
<form action="login.php" method="post" name="loginform" autocomplete="off" onSubmit="doChallengeResponse();">
<input type="hidden" name="login_challenge" value="<?php echo $challenge; ?>">
<input type="hidden" name="login_response" value="--------------------------------">
Benutzer: <input type="text" name="login_username" value="" size="30" maxlength="20">
Kennwort: <input type="password" name="login_p_field" value="" size="30" maxlength="20">
<input type="submit" name="login_submit" value=" Anmelden "></p>
</form>
3. Wenn der Client jetzt seinen Namen und sein Kennwort in das Formular einträgt und auf "Anmelden" klickt, dann passiert das folgende:
a) Das Passwort-Feld wird ausgelesen, geleert und der String wird mit MD5 gehasht.
b) Aus Benutzername, MD5 aus (a) und Challenge vom Server wird ein neuer MD5-Hash gebaut.
c) Der Benutzername, die Challenge und der MD5-Wert aus (b) werden an den Server geschickt.
4. Der Server liest die angegebene Challenge (falls vorhanden) aus der Datenbank und löscht den Satz. Danach kann er überprüfen, ob der Client mit REMOTE_ADDR die Challenge überhaupt benutzen darf und ob seine Kombination aus Benutzername + MD5(Kennwort) + Challenge denselben Wert ergeben.
Ist nicht auf meinem Mist gewachsen. Ist ein abgewandeltes System von dem, das Typo3 für das Backend benutzt.
Zuguterletzt natürlich noch: Wenn es wirklich sicher sein soll, dann sollte man natürlich unbedingt eine verschlüsselte Verbindung benutzen.
[Nachtrag]
Probleme kann es hier dadurch geben, dass bei Sonderzeichen (ä, ö, ü, also nicht-
ASCII) der Browser des Client ggf. einen anderen Zeichenwert benutzt als der Server, also dass der MD5-Hash von "häh" auf dem Client und auf dem Server unterschiedlich sind. 100% kriegt man das nur, wenn man keine Sonderzeichen im Namen und Kennwort erlaubt.
Um das "etwas" zu umgehen, habe ich die aufgeführte
md5.js etwas modifiziert (die allerletzte Routine). Hab' aber auch schon erlebt, dass es bei einem deutschen User trotzdem nicht mit Sonderzeichen ging.
Code:
/* Modified 2003-11-08 by V. Siebert to use charCodeAt to accept international characters */
function MD5(entree)
{
var l,s,k,ka,kb,kc,kd;
init();
for (k=0;k<entree.length;k++) {
l=entree.charCodeAt(k);
update(l);
}
finish();
ka=kb=kc=kd=0;
for (i=0;i<4;i++) ka+=shl(digestBits[15-i], (i*8));
for (i=4;i<8;i++) kb+=shl(digestBits[15-i], ((i-4)*8));
for (i=8;i<12;i++) kc+=shl(digestBits[15-i], ((i-8)*8));
for (i=12;i<16;i++) kd+=shl(digestBits[15-i], ((i-12)*8));
s=hexa(kd)+hexa(kc)+hexa(kb)+hexa(ka);
return s;
}