Frage mich gerade, ob man nicht einen digest auth login in django implementieren könnte.
Hab mal gesucht, aber nichts entsprechendes gefunden.
Eine Implementierung von RFC2617 gibt es alerdings in paste:
http://svn.pythonpaste.org/Paste/trunk/ ... /digest.py
digest auth mit django?
@jens: Das kommt darauf an, wie Django Benutzerpasswörter speichert. Um den für Digest-Auth nötigen HA1-Hash zu erhalten, ist das Benutzerpasswort im Klartext nötig. Man muss also entweder direkt den HA1-Hash oder das Klartext-Passwort in der Benutzerdatenbank speichern. Beides ist unschön.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Klartext Passwörter zu speichern ist natürlich eine schlechte Idee 
Irgendetwas zu speichern mit dem man ohne zusätzliches Wissen nutzten kann um sie ein zu loggen ist ebenfalls keine ganz so gute Idee
Auf der anderen Seite:
Demnach, wäre die einfachste Variante nach RFC 2069 das:
Der Client sendet:
In dem Fall muß ich auf dem Server mindestens HA1 speichern. Wenn jemand den DB Dump hat, kann er sich damit einloggen, kann aber das Klartext Passwort nicht rekonstruieren.
Erweitern kann man das ganze nach RFC 2517. Dabei blicke ich noch nicht ganz durch. Aber in der RFC ist ein Beispiel:
Das sendet der Server:
und das der Client zurück:
Vom Server kommt:
* qop - ein String der festlegt "was der Server zusätzlich kann"
* nonce und opaque - zwei unterschiedliche zufalls MD5 hexdigest
Der Client erstellt:
* nc - ein Zähler (request counter)
* cnonce - einen einmalige Zufallszahl
Was muß man in dem Fall auf dem Server speichern???
btw. Django speichert einen MD5 Hash mit einem Salt Wert.
EDIT: Kann es sein, das auch mit allen RFC 2517 Zusätzen, auf dem Server der gleiche HA1 gespeichert werden muß?
Man könnte evtl. in dem realm einen salt Wert einfügen?!?

Irgendetwas zu speichern mit dem man ohne zusätzliches Wissen nutzten kann um sie ein zu loggen ist ebenfalls keine ganz so gute Idee

Auf der anderen Seite:
- * Wenn kein http*s* benutzt wird, kann man mit einem gültigen Session Cookie schon rein kommen.
* Ohne alles, wird das Passwort im Klartext übertragen...
Demnach, wäre die einfachste Variante nach RFC 2069 das:
Code: Alles auswählen
HA1 = MD5(username + realm + password)
HA2 = MD5(method + digestURI)
Code: Alles auswählen
MD5(HA1 + nonce + HA2)
Erweitern kann man das ganze nach RFC 2517. Dabei blicke ich noch nicht ganz durch. Aber in der RFC ist ein Beispiel:
Das sendet der Server:
Code: Alles auswählen
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Code: Alles auswählen
Authorization: Digest username="Mufasa",
realm="testrealm@host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
qop=auth,
nc=00000001,
cnonce="0a4f113b",
response="6629fae49393a05397450978507c4ef1",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
* qop - ein String der festlegt "was der Server zusätzlich kann"
* nonce und opaque - zwei unterschiedliche zufalls MD5 hexdigest
Der Client erstellt:
* nc - ein Zähler (request counter)
* cnonce - einen einmalige Zufallszahl
Was muß man in dem Fall auf dem Server speichern???
btw. Django speichert einen MD5 Hash mit einem Salt Wert.
EDIT: Kann es sein, das auch mit allen RFC 2517 Zusätzen, auf dem Server der gleiche HA1 gespeichert werden muß?
Man könnte evtl. in dem realm einen salt Wert einfügen?!?
Der Server muss bei Digest Auth (egal ob nach RFC 2069 oder 2617) in der Lage sein, den HA1-Hash zu berechnen. Das kann er nur, wenn er entweder HA1-Hash oder Klartextpasswort zur Verfügung hat. Da hilft es auch nichts, "in das Realm einen Salt-Wert einzufügen" (was immer damit gemeint ist).
nonce, qop und opaque haben damit nichts zu tun, diese Werte dienen der Verifizierung eingehender Anfragen. In nonce und oqaque werden in der Regel Zeitstempel und/oder Zähler abgelegt. Das soll der Vermeidung von Replay-Attacken dienen.
Lies doch bitte RFC 2617, da ist das doch alles beschrieben (inkl. Sinn und Zweck der zusätzlichen Felder).
nonce, qop und opaque haben damit nichts zu tun, diese Werte dienen der Verifizierung eingehender Anfragen. In nonce und oqaque werden in der Regel Zeitstempel und/oder Zähler abgelegt. Das soll der Vermeidung von Replay-Attacken dienen.
Lies doch bitte RFC 2617, da ist das doch alles beschrieben (inkl. Sinn und Zweck der zusätzlichen Felder).
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
HA1 ist ja: MD5(username + realm + password)lunar hat geschrieben: "in das Realm einen Salt-Wert einzufügen" (was immer damit gemeint ist).
OK, der realm sollte wohl eh immer speziell für die eine Seite sein. Ist der allerdings auf mehreren Servern gleich, hat man auch den selbe HA1.
Wenn man also zu jedem realm eine Zufälligen Salt beimischt ist der HA1 immer unterschiedlich. So ein bishen ähnlich als Passwörter nur als Hash ohne salt zu speichern, was allgemein nicht empfohlen wird. Aber gut, hier sind eh noch zwei Teile zum password dabei.
Was spricht dagegen den HA1 auf dem Server zu speichern?
Wenn man den normalen Django salt+password Hash in die Finger bekommen würde, kann man damit nicht all zu viel anfangen. Beim HA1 kann man sich allerdings einloggen. Schade.
Gibt es eine Alternative, die in allen Browsern implementiert ist???
Ach so, die Idee mit dem Salt bezieht sich auf serverseitige Speicherung. Dazu ist das Realm nicht gedacht. "Realm" bezeichnet einen eindeutigen Authentifizierungsbereich der Seite, und sollte daher nicht benutzerspezifisch, sondern nur seitenspezifisch sein!
Gegen die Speicherung des HA1-Hashs spricht, dass die Authentifizierungsmethode der Datenbank dann eine ganz bestimmte Art der Speicherung (e.g. Klartext oder HA1-Hash) aufzwingt, was den späteren Wechsel der Authentifizierungsmethode erschweren kann, und das der Authentifizierungsbereich aka Realm in den Hash einfließt, so dass man eine Seite nicht beliebig in Bereiche aufteilen kann, wenn man den HA1-Hash serverseitig speichert.
Die in allen Browsern implementierte Alternative zu Digest-Auth heißt HTTPS …
Gegen die Speicherung des HA1-Hashs spricht, dass die Authentifizierungsmethode der Datenbank dann eine ganz bestimmte Art der Speicherung (e.g. Klartext oder HA1-Hash) aufzwingt, was den späteren Wechsel der Authentifizierungsmethode erschweren kann, und das der Authentifizierungsbereich aka Realm in den Hash einfließt, so dass man eine Seite nicht beliebig in Bereiche aufteilen kann, wenn man den HA1-Hash serverseitig speichert.
Das ist mehr oder weniger irrelevant. Wenn interne Werte aus der Benutzerdatenbank dem Angreifer in die Händen fallen können, bestehen viel größere Probleme. Wichtig ist vor allem, was bei der Authentifizierung übertragen wird, denn an frei durch den Äther gesendete Werte kommt man um Welten leichter heran als an die Passwort-Hashes aus der Benutzerdatenbank einer Seite.Wenn man den normalen Django salt+password Hash in die Finger bekommen würde, kann man damit nicht all zu viel anfangen. Beim HA1 kann man sich allerdings einloggen. Schade.
Die in allen Browsern implementierte Alternative zu Digest-Auth heißt HTTPS …
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Du meinst X.509-Zertifikate? Wenn ich mich im Semester so umsehe kommen damit teilweise nichtmal Informatik-Studenten zurecht.lunar hat geschrieben:Die in allen Browsern implementierte Alternative zu Digest-Auth heißt HTTPS …
(Ob das jetzt mehr über X.509 oder Informatikstudenten aussagt daf jeder selbst entscheiden)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nein, ich meine einfach nur Transportverschlüsselung. Alle Gedanken über über eine Krücke wie Digest-Auth kann man sich dann völlig sparen, und einfach bedenkenlos eine normale Formular-Anmeldung mit Klartext-Passwort verwenden, ohne Konsequenzen für die Sicherheit fürchten zu müssen.
Zertifikate sind nettes Beiwerk, aber Transportverschlüsslung ist wirklich wichtig …
Zertifikate sind nettes Beiwerk, aber Transportverschlüsslung ist wirklich wichtig …
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
https in Django zu implementieren dürfte allerdings viel zu kompliziert sein 
Hab aber was gefunden:
HTTP Digest Authentication in Django: http://bitbucket.org/akoha/django-digest/wiki/Home
Dabei wird, ähnlich wie bei meinem JS-SHA-Login, parallel zum Django Password der HA1 generiert und gespeichert.
btw. Basic Auth gibt es auch, fertig: http://www.djangosnippets.org/snippets/243/

Hab aber was gefunden:
HTTP Digest Authentication in Django: http://bitbucket.org/akoha/django-digest/wiki/Home
Dabei wird, ähnlich wie bei meinem JS-SHA-Login, parallel zum Django Password der HA1 generiert und gespeichert.
btw. Basic Auth gibt es auch, fertig: http://www.djangosnippets.org/snippets/243/
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Warum sollte man das nicht haben? Es ist 2010, SSL gibt es seit etwa 15 Jahren und es ist wohl die mit Abstand am weitesten verbreitete Transportverschlüsselung auf dem Planeten, da erwartet man dass ein Webserver das unterstützt.jens hat geschrieben:bzw. wenn man von Apache aus keine Möglichkeit dazu hat.
Wäre ja lächerlich, das Rad neu zu erfinden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Warum soll eine Applikation etwas machen was aufgabe des Frontends ist?jens hat geschrieben:Ich meinte, eine https Implementierung in Django selbst. Damit man z.B. https mit dem dev Server hat bzw. wenn man von Apache aus keine Möglichkeit dazu hat.
@jens: Transportverschlüsselung ist nicht Aufgabe der Anwendung, sondern des Servers. Wenn der Server bzw. der Hosting-Anbieter Transportverschlüsselung nicht bietet, eine sichere Authentifizierung aber Voraussetzung für den Betrieb ist, dann muss Du in logischer Konsequenz Server und/oder Anbieter wechseln.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
@lunar: Da hast du natürlich recht. Das ganze ist aber auch eine Budget Frage. Denn ein echtes Zertifikat kostet i.d.R. Geld.
Es geht hier nicht um einen Shop.
In erster Linie geht es mit darum keine Passwörter im Klartext zu verschicken, so wie es z.B. in diesem Forum der Fall ist.
Ich dachte Digest-Auth wäre da evtl. eine Alternative. Aber ich bleib dann wohl lieber bei meinem JS-SHA-Login. Den habe ich auch gerade erst neu implementiert, denn nun nutzte ich jQuery und alles geht per Ajax. (ist noch nicht comittet) Wenn ich Zeit finde, dann werde ich daraus mal eine separate "Reuseable Dango App" machen.
Es geht hier nicht um einen Shop.
In erster Linie geht es mit darum keine Passwörter im Klartext zu verschicken, so wie es z.B. in diesem Forum der Fall ist.
Ich dachte Digest-Auth wäre da evtl. eine Alternative. Aber ich bleib dann wohl lieber bei meinem JS-SHA-Login. Den habe ich auch gerade erst neu implementiert, denn nun nutzte ich jQuery und alles geht per Ajax. (ist noch nicht comittet) Wenn ich Zeit finde, dann werde ich daraus mal eine separate "Reuseable Dango App" machen.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Ein selbstsigniertes oder von CACert-signiertes Zertifikat kostet kein Geld und wenn man damit Leben kann dass man keine CA hat, der man vertrauen kann (wobei hier wiederrum die frage aufkommt welcher CA man tatsächlich auch vertrauen will) dann ist das von der Sicherheit der Daten genauso gut wie ein kostenpflichtiges Zertifikat.jens hat geschrieben:@lunar: Da hast du natürlich recht. Das ganze ist aber auch eine Budget Frage. Denn ein echtes Zertifikat kostet i.d.R. Geld.
Also ich würde selbstsigniertes HTTPS etwa unendlich oft einem selbstzusammengebastelten SHA-JS-Whatever-Login vorziehen.jens hat geschrieben:Ich dachte Digest-Auth wäre da evtl. eine Alternative. Aber ich bleib dann wohl lieber bei meinem JS-SHA-Login. Den habe ich auch gerade erst neu implementiert, denn nun nutzte ich jQuery und alles geht per Ajax. (ist noch nicht comittet) Wenn ich Zeit finde, dann werde ich daraus mal eine separate "Reuseable Dango App" machen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
@jens: Was ist denn Dein „JS-SHA-Login“? Das bedeutet doch nicht etwa, dass Du das Passwort per Javascript hasht und erst dann versendest?! Dann wäre Digest-Auth nämlich eine um Welten bessere Alternative (und HTTPS sowieso) …
Und es muss doch im Übrigen auch kein Zertifikat einer anerkannten CA sein. Verschlüsseln kann man auch mit einem selbst ausgestellten Zertifikat. Da die meisten Benutzer (mich eingeschlossen) Zertifikate eigentlich nie prüfen, ist der Sicherheitsverlust eines selbst ausgestellten Zertifikats gegenüber einem "echten" CA-Zertifikat eigentlich recht marginal …
Und es muss doch im Übrigen auch kein Zertifikat einer anerkannten CA sein. Verschlüsseln kann man auch mit einem selbst ausgestellten Zertifikat. Da die meisten Benutzer (mich eingeschlossen) Zertifikate eigentlich nie prüfen, ist der Sicherheitsverlust eines selbst ausgestellten Zertifikats gegenüber einem "echten" CA-Zertifikat eigentlich recht marginal …
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Mein "JS-SHA-Login" macht mehr als bloß einen Hash vom Password zu senden. Siehe: http://www.pylucid.org/permalink/42/sic ... ohne-https
Es ist schon ähnlich dem Digest Auth verfahren, aber:
1. es wird SHA1 statt MD5 verwendet
2. Auf dem Server wird nur ein Teil gespeichert mit dem man alleine nichts anfangen kann. (genau genommen wird ein Teil mittels XOR verschlüsselt)
Und Punkt 2 ist eigentlich das, was mich an Digest Auth am meisten stört.
Wie der JS-SHA-Login genau abläuft, steht hier: http://www.pylucid.org/permalink/34/js- ... seudo-code
Der eigentliche soucecode ist hier: http://trac.pylucid.net/browser/branche ... s/crypt.py
Bin für Kritik, wie man es noch besser manchen könnte, offen.
Wir müssen uns nicht darüber streiten, das https das beste wäre. Das ist mir auch klar. Aber wie viele Seiten setzten es ein, wenn es nicht gerade ein Shop ist? Diese Forum? Ubuntuusers? Fast niemand, wenn es nichts "kritisches" ist. Und meine Homepage sehe ich auch nicht als so "kritisch" an.
Aber wenn ich mich mal aus einem fremden Netz (z.B. an der Uni) einloggen möchte, ist es mit doch etwas unbehaglich, mein Passwort im Klartext zu verschicken. Zwar nutzte ich für jede Seite ein eigenes Passwort, aber dennoch...
EDIT: Ah, eine alternative wäre dann noch:
http://en.wikipedia.org/wiki/CRAM-MD5
http://en.wikipedia.org/wiki/HMAC
Es ist schon ähnlich dem Digest Auth verfahren, aber:
1. es wird SHA1 statt MD5 verwendet
2. Auf dem Server wird nur ein Teil gespeichert mit dem man alleine nichts anfangen kann. (genau genommen wird ein Teil mittels XOR verschlüsselt)
Und Punkt 2 ist eigentlich das, was mich an Digest Auth am meisten stört.
Wie der JS-SHA-Login genau abläuft, steht hier: http://www.pylucid.org/permalink/34/js- ... seudo-code
Der eigentliche soucecode ist hier: http://trac.pylucid.net/browser/branche ... s/crypt.py
Bin für Kritik, wie man es noch besser manchen könnte, offen.
Wir müssen uns nicht darüber streiten, das https das beste wäre. Das ist mir auch klar. Aber wie viele Seiten setzten es ein, wenn es nicht gerade ein Shop ist? Diese Forum? Ubuntuusers? Fast niemand, wenn es nichts "kritisches" ist. Und meine Homepage sehe ich auch nicht als so "kritisch" an.
Aber wenn ich mich mal aus einem fremden Netz (z.B. an der Uni) einloggen möchte, ist es mit doch etwas unbehaglich, mein Passwort im Klartext zu verschicken. Zwar nutzte ich für jede Seite ein eigenes Passwort, aber dennoch...
EDIT: Ah, eine alternative wäre dann noch:
http://en.wikipedia.org/wiki/CRAM-MD5
http://en.wikipedia.org/wiki/HMAC
@jens: XOR ist keine Verschlüsselung 
Wenn Du schon a priori davon ausgehst, dass die serverseitige Datenbank offen liegt, und man daraus HA1-Hashes auslesen kann, kann man über Sicherheit kaum sinnvoll diskutieren. Denn wenn der Angreifer tatsächlich so weit kommt, HA1-Hashes aus der Datenbank lesen zu können, dann ist das Auslesen des Hashes noch das geringste Problem. Schließlich kann der Angreifer dann unter Umgehung der Seite und deren Authentifizierungsmechanismen auch direkt die Datenbank manipulieren oder zumindest auslesen, und so noch weitaus größeren Schaden anrichten.
Insofern verstehe ich nicht, warum Du Dich daran, dass bei Digest-Auth eine verwertbare Vorstufe des Algorithmus serverseitig gespeichert werden muss, denn nüchtern betrachtet ist das eigentlich vollkommen egal, Dein Verfahren ist nicht sicherer oder unsicherer als Digest-Auth.
Beide Verfahren haben dieselben Probleme, und sind nur ein zusätzliches Hindernis, aber kein echter Schutz. Gegen einen Man-in-the-Middle-Angriff bieten beide Verfahren nicht den geringsten Schutz, sondern erhöhen der Aufwand nur ein kleines Stück.
Insofern ist HTTPS auch nicht das „beste“, sondern das einzig richtige und sichere.

Wenn Du schon a priori davon ausgehst, dass die serverseitige Datenbank offen liegt, und man daraus HA1-Hashes auslesen kann, kann man über Sicherheit kaum sinnvoll diskutieren. Denn wenn der Angreifer tatsächlich so weit kommt, HA1-Hashes aus der Datenbank lesen zu können, dann ist das Auslesen des Hashes noch das geringste Problem. Schließlich kann der Angreifer dann unter Umgehung der Seite und deren Authentifizierungsmechanismen auch direkt die Datenbank manipulieren oder zumindest auslesen, und so noch weitaus größeren Schaden anrichten.
Insofern verstehe ich nicht, warum Du Dich daran, dass bei Digest-Auth eine verwertbare Vorstufe des Algorithmus serverseitig gespeichert werden muss, denn nüchtern betrachtet ist das eigentlich vollkommen egal, Dein Verfahren ist nicht sicherer oder unsicherer als Digest-Auth.
Beide Verfahren haben dieselben Probleme, und sind nur ein zusätzliches Hindernis, aber kein echter Schutz. Gegen einen Man-in-the-Middle-Angriff bieten beide Verfahren nicht den geringsten Schutz, sondern erhöhen der Aufwand nur ein kleines Stück.
Insofern ist HTTPS auch nicht das „beste“, sondern das einzig richtige und sichere.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Es muss nicht immer gleich ein Hacker auf der Maschine sein. z.B. kann man so keinen SQL Dump aus den Fingern geben, deswegen mag ich ehr ungern HA1 auf dem Server speichern... Und wenn das der einzige Mehrwert von JS-SHA-Login ist, dann ist das auch schon mal etwas, oder nicht?
Aber du hast natürlich recht, wenn ein Hacker auf der Maschine ist, ist eh alles verloren. Da hilft aber auch kein https
Ach, in der Vergangenheit hat es auch Man-in-the-Middle Angriffe auf https Verbindungen gegeben... Und da sind wir wieder bei den Zertifikat Problem. Ohne ein echtes, hat der Mann in der Mitte es einfacher, oder nicht?
Aber du hast natürlich recht, wenn ein Hacker auf der Maschine ist, ist eh alles verloren. Da hilft aber auch kein https

Ach, in der Vergangenheit hat es auch Man-in-the-Middle Angriffe auf https Verbindungen gegeben... Und da sind wir wieder bei den Zertifikat Problem. Ohne ein echtes, hat der Mann in der Mitte es einfacher, oder nicht?