Seite 1 von 2
"Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 08:30
von Bodyslam
Hallo Leute,
ich arbeite mich gerade in Webseitengestaltung ein und habe mit dem Groß davon auch keine Probleme, jedoch bin ich jetzt schon seit einige Tagen dabei, ein ordentlichen Login zu gestalten, also einer der auch vertrauenswürdig ist. Daher hier mal ein paar Fragen.
Im Forum hier steht jetzt schon eine ganze Menge und da hat wohl jeder eine andere Meinung zu. Meine Idee wäre nun folgender, ein User meldet sich an, damit gibt er PW und Username an, dies wird per https gesendet (PW md5 gehasht). Serverseitig wird mit dem Namen in der DB gesucht und mit der dazugehörigen (bei der Registrierung random erstellten) Nummer ein Hexdigest gebildet. Stimmt das dann mit dem PW-Eintrag zusammen folgt alles andere. Da Leute von außen kein Zugriff auf die DB haben und die Daten sicher per https übertragen werden, sollte es doch im Grunde ein "sicherer" Login sein der ohne größeren Aufwand nicht zu knacken ist, wenn ich das falsch sehe berichtigt mich bitte, da mir das jetzt schon ein paar Tage durch den Kopf geht.
MfG
B.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 09:24
von kbr
Im Prinzip sind Deine Überlegungen richtig. Bereits das Login hat per https zu erfolgen, damit die User-Passwort Kombination verschlüsselt übertragen wird. Wie sicher das ist sei jetzt mal dahin gestellt, genauso ob es diejenigen, die es knacken können, interessiert.
Richtig ist weiter, dass auf Serverseite die Passwörter nicht im Klartext vorliegen sollten, sondern als Hash, der keinen Rückschluß auf den ursprünglichen Wert zulässt. md5 ist dieser Hinsicht mittlerweile aber zu schwach.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 09:39
von Bodyslam
Danke für die schnelle Antwort. Als anstatt md5 könnte man ja auch sha nehmen; was würdest du anders machen von der Logik des Ablaufes? Mir geht es eben darum, dass ich ordentliches Login habe, eine Seite die ständig gehackt wird weil das nicht sicher ist, ist unsinn.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 10:06
von kbr
Der Ablauf ist wie folgt: Benutzername und Passwort werden per https an den Server übertragen. Dort wird aus dem Passwort ein Hashwert gebildet und geprüft, ob die Benutzername-Hashwert Kombination als Login erlaubt ist.
Das Übertragen des Passwort bereits als Hash (falls ich Dich richtig verstanden habe) erhöht die Sicherheit nicht.
Wichtig ist bei diesem Schritt die Sicherheit der Datenübertragung an sich.
Auf Serverseite sieht es so aus, dass ein unknackbarer Server die Passwörter auch im Klartext speichern könnte. In der Praxis ist davon auszugehen, dass die Passwortdatei zugänglich ist, und sei es durch Personal, das einen regulären Zugang hat.
Deshalb dürfen die Passwörter nur verschlüsselt vorliegen, idealerweise in einer Einwegverschlüsselung. Ob die einer "Rückübersetzung" standhält, hängt von der Zahl möglicher Kombinationen und der eingesetzten Rechenleistung ab.
md5 ist heute zu knacken. Der aktuelle Stand bei sha ist mir nicht bekannt.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 10:47
von DanJJo
Ich habs so gemacht
Code: Alles auswählen
# From https://github.com/mitsuhiko/python-pbkdf2
import os, sys, re
import hashlib
from os import urandom
from base64 import b64encode, b64decode
from itertools import izip
from pbkdf2 import pbkdf2_bin
SALT_LENGTH = 12
KEY_LENGTH = 24
HASH_FUNCTION = 'sha256'
COST_FACTOR = 10000
# Parameters to PBKDF2. Only affect new passwords
def make_hash(password):
if isinstance(password, unicode):
password = password.encode('utf-8')
salt = b64encode(urandom(SALT_LENGTH))
return 'PBKDF2${}${}${}${}'.format(HASH_FUNCTION,COST_FACTOR,salt,b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,getattr(hashlib, HASH_FUNCTION))))
def check_hash(password, hash_):
if isinstance(password, unicode):
password = password.encode('utf-8')
algorithm, hash_function, cost_factor, salt, hash_a = hash_.split('$')
assert algorithm == 'PBKDF2'
hash_a = b64decode(hash_a)
hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
getattr(hashlib, hash_function))
assert len(hash_a) == len(hash_b)
diff = 0
for char_a, char_b in izip(hash_a, hash_b):
diff |= ord(char_a) ^ ord(char_b)
return diff == 0
funktioniert lokal gut...im "internet" irgendwie nicht bekomme ein bad request? liegts daran, dass er auf dem server import os etc nicht findet?
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 12:16
von BlackJack
@DanJJo: Woran der "Bad Request" liegt kann man so schlecht beantworten, denn das gezeigte hat ja mit Internet/HTTP erst einmal überhaupt nichts zu tun.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 12:31
von DanJJo
Na Gut also in der main.py
route zum senden der register daten...
Code: Alles auswählen
@route('/register_submit', method='POST')
@route('/register_submit/', method='POST')
def register_submit(db):
name = (request.forms.get('usernamesignup')).decode('utf-8')
mail = request.forms.get('emailsignup').decode('utf-8')
matrnr = request.forms.get('matrnrsignup').decode('utf-8')
password = (request.forms.get('passwordsignup')).decode('utf-8')
password_confirm = (request.forms.get('passwordsignup_confirm')).decode('utf-8')
dat = date.today()
sql = db.execute('SELECT StudName, StudMail, StudMatrNr FROM Student WHERE StudName=? or StudMail=? or StudMatrNr=?',(name,mail,matrnr,))
row = sql.fetchone()
if row:
return "/register"
else:
if password == password_confirm:
pwhash = make_hash(password)
response.set_cookie("account", name, secret='BlaBla', path="/")
sql=db.execute('INSERT INTO Student(StudName,StudMail,StudMatrNr,StudPassword,StudAdmin,StudTele,FirstName,SecName,TimeStamp,free) VALUES (?,?,?,?,?,?,?,?,?,?)',(name,mail,matrnr,pwhash,'0','123456','Default','Default',dat,'0',))
return "/hauptmenu"
else:
return "/register"
register.tpl
Code: Alles auswählen
<script>
(function() {
$('.regi').bind("submit", function() {
$.ajax({
type: "POST",
url: "{{script}}/register_submit",
data: "&usernamesignup=" + $("#usernamesignup").val() + "&emailsignup=" + $("#emailsignup").val() + "&matrnrsignup=" + $("#matrnrsignup").val() + "&passwordsignup=" + $("#passwordsignup").val() + "&passwordsignup_confirm=" + $("#passwordsignup_confirm").val(),
success: function(response)
{
$("#contenti").hide().load("{{script}}"+response).fadeIn(2000);
}
});
return false;
});
})();
</script>
<div id="insert_container" >
<div id="wrapper_pages_small">
<div id="pages_style_small" class="regi">
<form id="submitregi" method="POST" action="/register_submit">
<h1> Willkommen </h1>
<h2> REGISTER </h2>
<ul>
<li>
<p>
<label for="username" class="uname" data-icon="u">Benutzername :</label>
</p>
</li>
<li>
<p>
<input id="usernamesignup" name="usernamesignup" required="required" type="text" placeholder="Benutzername" />
</p>
</li>
<li>
<p>
<label for="emailsignup" > E-mail :</label>
</p>
</li>
<li>
<p>
<input id="emailsignup" name="emailsignup" required="required" type="email" placeholder="beispiel@mail.de"/>
</p>
</li>
<li>
<p>
<label for="matrnr" class="matnr" data-icon="m">MatrikelNr :</label>
</p>
</li>
<li>
<p>
<input id="matrnrsignup" name="matrnrsignup" required="required" type="text" placeholder="123456789" />
</p>
</li>
<li>
<p>
<label for="passwordsignup" class="youpasswd" data-icon="p">Passwort :</label>
</p>
</li>
<li>
<p>
<input id="passwordsignup" name="passwordsignup" required="required" type="password" placeholder="Passwort"/>
</p>
</li>
<li>
<p>
<label for="passwordsignup_confirm" class="youpasswd" data-icon="p">Passwort bestätigen :</label>
</p>
</li>
<li>
<p>
<input id="passwordsignup_confirm" name="passwordsignup_confirm" required="required" type="password" placeholder="Passwort erneut eingeben"/>
</p>
</li>
<li>
<p class="signin button">
<input type="submit" value="Registrieren"/>
</p>
</li>
<li>
<hr />
<p id="tipp">bereits Registriert?<a class="change_link" href="../login"> Login </a></p>
</li>
<ul>
</form>
</div>
</div>
</div>
so und wenn ich nun
weg lasse läuft er ohne BadRequest durch (im Internet (natürlich muss ich dann auch den eintrag in die DB weg nehmen). Lokal funktioniert das alles problemlos.Kann ich also davon ausgehen, dass es irgendwas mit den Importen zu tun hat ..sprich auf meinem rechner kann ich os..etc importen und auf dem server nicht?
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 13:29
von BlackJack
@DanJJo: Nicht zwingend, das kann auch an allem möglichen anderen Sachen liegen. Wenn wir von Internet reden, dann immer noch von Uberspace.de? Da kannst Du Dich doch einfach anmelden und es im Python-Interpreter live ausprobieren ob es sich importieren lässt und auch die Funktion(en) mal ausprobieren.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 14:01
von DanJJo
ja wir reden von Uberspace. Also die sachen lassen sich importieren. Die Funktion ergibt folgenden fehler
hab mal alles manuel eingegeben
Code: Alles auswählen
return 'PBKDF2${}${}${}${}'.format('sha256',10000,salt,b64encode(pbkdf2_bin(password, salt, 10000, 24,getattr(hashlib, 'sha256'))))
ValueError: zero length field name in format
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 16:18
von BlackJack
@DanJJo: '{}' als Platzhalter geht erst ab Python 2.7. Also entweder Python 2.7 benutzen oder bei 2.6 gültige Platzhalter, also mit Indexnummer, verwenden.
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 23:48
von Bodyslam
kbr hat geschrieben:
...
Das Übertragen des Passwort bereits als Hash (falls ich Dich richtig verstanden habe) erhöht die Sicherheit nicht.
Wichtig ist bei diesem Schritt die Sicherheit der Datenübertragung an sich.
...
Ich versuche Lösungen ohne JS in den sensibelen Bereichen einzusetzen, um die mögliche Fehlerquellen zu begrenzen, darf ich daher deiner Antwort entnehmen, dass das PW nicht gehasht übertragen werden muss bei einer https-Verbindung? Oder meinst andere Methoden um die Sicherheit der Datenübertragung zu verbessern?
Re: "Sicherer" Webseiten Login
Verfasst: Mittwoch 3. Juli 2013, 23:53
von Bodyslam
@DanJJo
Arbeitest du mit einem Framework? Der Code sieht mir komplett selbsterstellt aus, existiert für die Aufgabe, die du realisierst, nicht eine fertige Lösung?
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 06:57
von BlackJack
@Bodyslam: DanJJo verwendet das Mikrorahmenwerk
Bottle. Aber anscheinend nichts für die Form-Verarbeitung und auch kein ORM. Ich verwende da gerne WTForms und SQLAlchemy wenn ich mit Bottle beziehungsweise mit SQL-Datenbanken im allgemeinen arbeite.
@DanJJo: Schau mal in die Dokumentation wie man Unicode-Objekte von `request.query` beziehungsweise `FormsDict`-Exemplaren im allgemeinen bekommen kann:
Request Data.
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 10:29
von Bodyslam
Ich habe mir da eine andere Kombo zusammengestellt. Bottle hatte ich mir auch mal angesehen, aber Cherrypy fand ich dann doch etwas ausgereifter und die Konfigurationoption(en) dort besser. Da ich ungerne mit SQL arbeite, bin ich bei MongoDB geblieben. Mit CherryPy und Moody-Templates ist das schon eine angenehme Sache. Für Angelegenheiten wie hier besprochen muss ich nur mal in JS reinschauen, damit ich auch tatsächlich ein ordentliches Login hinbekomme.
Danke nochmal für die Tipps, damit bekomme ich bestimmt schon was gutes hin, aber der erste Codesnippet von DanJJo ist schon eine starke Nummer

Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 11:17
von kbr
Bodyslam hat geschrieben:darf ich daher deiner Antwort entnehmen, dass das PW nicht gehasht übertragen werden muss bei einer https-Verbindung?
Angenommen das Passwort wird als Hashwert übertragen. Dann kann der Server hieraus nicht auf das ursprüngliche Passwort schließen, sondern muss den Hashwert als gültiges Passwort verwenden. Nimm nun weiter an, dass die Übertragung abgehört und entschlüsselt wird. Dann ist es völlig unerheblich, ob das Passwort oder dessen Hash übertragen wurde, da beide gleichwertig ein erfolgreiches Login ermöglichen.
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 12:16
von Bodyslam
Aber ich denke dass die Möglichkeiten des Abhörens mit https eingeschränkt/nicht möglich sind? was stimmt denn nun?
(Ausschnitt aus Wikipedia) ... ist ein Kommunikationsprotokoll im World Wide Web, um Daten abhörsicher zu übertragen.
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 12:41
von BlackJack
@Bodyslam: Das Problem bei SSL ist, das kaum ein Anwender tatsächlich die Zertifikate prüft, und viele Anwender selbst bei unpassenden Zertifikaten die Warnungen vom Browser einfach abnicken, und das nicht wirklich jede CA die in den gängigen Browsern als vertrauenswürdig hinterlegt sind, das auch tatsächlich ist.
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 14:27
von Bodyslam
Achso, also sowas wie Fakezertifikate, dass ist doch dann ein Problem des Webseitenbesuchers?. Aber wenn ich das Recht verstehe, sind die Beteiligten doch, der Austeller des Zertifikates, der Nutzer(also User der Internetseite) und der Domainbetreiber. Wenn also der Code sauber programmiert ist, das Zertifikat seriös, der Host up-to-date sollten doch die Fehlerquellen gering sein oder?
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 18:10
von cofi
1. CA wird vom Browser als vertrauenswuerdig gefuehrt
2. CA stellt Zertifikate fuer Websites aus - gefaelschte oder "echte" - fuer die es aber schon Zertifikate gibt
3. Angreifer mogelt diese Zertifikate dem Besucher unter
4. Besucher bemerkt bei einem handelsueblichen Browser niemals, dass er falsche Zertifikate bekommen hat
Natuerlich ist das immer ein Problem des Besuchers, wessen auch sonst? Aber wenn du den Aufwand schon treibst, dann willst du ihn doch auch schuetzen? Es gibt sehr weniger Szenarien in denen der Betreiber hier tatsaechlich den Schaden (mit-)traegt.
Re: "Sicherer" Webseiten Login
Verfasst: Donnerstag 4. Juli 2013, 18:49
von Bodyslam
Ok, also ist der Schaden dann obligatorisch beim Nutzer des Dienstes. Wie sieht es dann da mit einer Lösung aus? Könnte man nicht ganz banal (wenn man beim Zertifikat bleibt) dem User einfach Anzeigen welches Zertifikat die Seite nutzt? Da ich mich gerade mit JS einarbeite kann ich da leider nicht viel beisteuern, aber ist es nicht möglich per JS das Zertifikat, welches die Domain nutzt, mit dem zu vergleichen welches im Browser des Nutzers ankommt?