Salt sicherheit



  • Sqwan schrieb:

    So ein Quatsch. Wieso wird mein Hash und mein Salt den kleiner wenn ich die beiden untereinander mische?

    Du verlierst keine Bits beim Mischen. Mischen ist nicht falsch.
    Aber unnötig. Lieber den Code einfach halten.

    Mal was allgemeines zum Salten. Ich gehe davon aus, daß der Angreifer irgendwie das user- und passwort-Feld der Datenbank auslesen konnte. Irgendwas mit SQL-Injection oder der Provider hat die Datenbanken gegen Lesen durch andere Domainmieter auf dem selben Server nicht genug gesichert oder sowas.

    Stellen wir und vor, es wird nur md5(password) abgespeichert. Dann muß man nur einen Wörterbuchangriff gegen die md5s laufen lassen und bekommt viele Passwörter. Außerdem gibts genügend online-md5-reverse-Passwort-Datenbanken. Man gibt den md5-Code ein und bekommt sofort das Passwort.

    Das nächste Level ist ein Salt, der im Forum hardcoded ist und aus zwei Buchtaben besteht. Zum Beispiel beim Ultimate-Bulletin-Board "uu". Man speichert immer md5("uu".password). Nun steht das Ding nicht mehr fertig in einer Datenbank. Wenn man aber weiß, welche Board-Software benutzt wird, kann man den Wöterbuchangriff fahren.

    Das nächste Level ist, daß bei Einrichtung der Datenbank ein zweibuchstabiger Salt gewürfelt wird. Dann muß man 26*26*Wörterbuchangriff fahren. Damit bekommt man den Salt und kann den Rest normal Wörterbüchern.

    Man könnte den Salt pro User würfeln, und in die Datenbank tun. Hat gar keinen Zweck. Der Angreifer, der zwei Felder lesen konnte, kann auch drei lesen. 😮

    Jetzt zu den Rainbow-Tables. Damit kann man einigermaßen erträglich eine Vollanalyse aller Passwörter abspeichern. Man braucht für achtbuchstabige a-z-Passwörter bei weitem nicht 26^8 Platz. Dafür dauert die Abfrage eines md5-codes ein paar Milliarden Takte (aber bei weitem nicht 26^8*md5() Takte!!!). Trotzdem muß jedes mögliche Passwort bei table-Erstellung mal durchgerechnet werden. Deswegen gibt es Rainbow-Tables für beschränkte Zeichensätze und Passwortlängen. Und lustigerweise noch keine mit Umlauten äöü! Also Umlaute in den salt und schon ists Sense. Warum nur Umlaute? Der Salt muß doch gar nicht eingebbar sein. Einfach Zufallsbytes nehmen aus dem nicht eingebbaren Bereich.

    Und nicht in der Datenbank abspeichern, sondern woanders.

    Zur Obfuscation durch Vermischung: md5 vermisch die Bits zuverlässig und unnachvollziehbar. Es vermischt durch eine Vorstufe nicht besser. Statt md5(misch(salt,pwassword)) könnnte man auch md5(md5(salt.password)) nehmen. Aber md5(md5(x)) darf nicht besser sein als md5(x). Alles, was Du mit dem misch() machst, ist daß Du Dich gegen Datenbankabgespeicherte reverse-Lookups zum Beispiel mit zweibuchstabigen salts sicherst. Aber das kannst Du viel besser machen, indem Du fett mal 20 Buchstaben nimmst. Oder 40? md5 füllt vor der Verarbeitung eh auf 512 bit = 64 byte auf. Dann wird's, solange der User weniger als 24 Zeichen als Passwort nimmt, nichtmal langsamer. Also was soll der Geiz?

    Gegen was soll eigentlich geschützt werden? Gegen "Der Angreifer kann die User-Tabelle lesen" sollte das reichen.
    Daß der Angreifer den Code nicht lesen kann, muß man auch was machen, aber anders. Zum Beispiel bei mir habe ich immer Befürchtungen, daß der Apache verfummelt ist und *.pl mal offen zeigt. Und vor allem, daß ich im Zuge einer Forumsdiskussion mal forumCodeComplete.rar poste. Dagegen tat ich die Datenbank-Passwörter in die require('../passwords.pl'), dann rare ich sie nicht mit und sie sind auch nicht mehr im apache-abfragbaren Bereich. Der Salt würde auch dahin wandern.



  • also ich gehe davon aus, das mein Angreife auf Gott weiß welche Art und Weise an die daten aus der Datenbank kommt.

    Mein aktuelles System sieht folgendermaßen aus:
    1. Teil ist das Passwort
    2. Teil ist ein 300 Zeichen langer fester Salt aus diversen Sonderzeichen so wie Buchstaben inklusive Umlauten.
    3. Teil ist ein zufällig generierter Salt. Dieser Basiert nicht nur auf der Zeit!

    Den Salt aus 3. muss ich in der DB speichern. Das ist natürlich ziemlich Witzlos, weil der der mein PWD hash hat kriegt auch den Salt hash aus der DB. Jetzt würde ich es natürlich gerne so einrichten das jemand ohne meinen ganzen Code mit dem Salthash aus der DB nichts anfangen kann.
    Dazu Mische ich a) den Hash in sich und wollte b) teile aus pwd-hash und salt-hash austauschen.

    Zur Zeit ist mein fester Salt normal im Code.
    Den könnte ich ja auch nach require('../passwords.pl') verschieben.
    Und da könnte ich dann auch variablen festlegen nach denen der hash gemischt und vertauscht wird?

    md5(misch(salt,pwassword)) <-- Das habe ich nicht vor!

    austauschen( misch(md5(pwd.salt1.salt2)), misch(md5(zufallssalt))) <-- Das habe ich vor...

    dabei ist salt2 = md5(zufallssalt)
    Das ergebnis sind dann 2 neue hashs, die aber eigentlich so garkeine sind, sondern nur durch

    zurücktasuch( zurückmisch(pwd), zurückmisch(salt) ) zu den echten hashs werden.

    Ihr geht also beide davon aus, dass das mischen keinen Nachteil für die sicherheit mitbringt? Dann kann ichs einfach einbauen. Obs jetzt sicherer wird ist ja erstmal egal solange es nicht unsicherer wird.

    Ach ja. Der Zufallsanteil im Salt ist mir sehr wichtig, da ich nicht möchte, das gleiche passwörter in der Datenbank auch gleich aussehen.



  • "Besser" impliziert "Anders" aber "Anders" impliziert noch lange nicht "Besser"

    steht in deiner signatur und du versuchsts auf biegen und brechen anders zu machen aber dadurch wirds nicht besser...



  • no_code schrieb:

    "Besser" impliziert "Anders" aber "Anders" impliziert noch lange nicht "Besser"

    steht in deiner signatur und du versuchsts auf biegen und brechen anders zu machen aber dadurch wirds nicht besser...

    👍

    Gut... Ist also Käse? Aber wie ist es dann besser? Salt fest im Code? Kann ich machen. Hab ich ja auch. Allerdings jetzt durch zufall 300 zeichen... Und man kann gleiche pwds noch erkennen.



  • Sqwan schrieb:

    Und man kann gleiche pwds noch erkennen.

    Ja, dagegen helfen die Datenbanksalts.
    Aber austauschen( misch(md5(pwd.salt1.salt2)), misch(md5(zufallssalt))) ist doch nicht besser als md5(salt1.salt2.pwd) mit salt1=hardcoded und salt2=userid. WOmit ich nebenbei sage, daß salt2 aus der Datenbank nichts davon hat, daß er supi zufällig und "nicht allein auf der Uhrzeit basierend" ist.
    (abgesehen davon, daß es Zweifel an md5 selber gibt und du statt einem hash-feld mit md5 auch drei mit md5, sha1 und ripmed160 nehmen kannst).



  • ^^ Eben das ist mir auch aufgefallen, also das der supi zufällige salt nichts davon hat supi zufällig zu sein wenn der angreifer ihn womöglich eh hat.

    volkard schrieb:

    Ja, dagegen helfen die Datenbanksalts.
    Aber austauschen( misch(md5(pwd.salt1.salt2)), misch(md5(zufallssalt))) ist doch nicht besser als md5(salt1.salt2.pwd) mit salt1=hardcoded und salt2=userid. WOmit ich nebenbei sage, daß salt2 aus der Datenbank nichts davon hat, daß er supi zufällig und "nicht allein auf der Uhrzeit basierend" ist.

    Eben da liegt das problem weshalb ich den ganzen aufstand betreibe. Ich hatte mir erhofft, dass der DB-Salt eben doch was davon hat zufällig zu sein. Aber gut... wenn ich durch vermischen keinen vorteil habe kann ich tatsächlich auch die id anhängen.

    volkard schrieb:

    (abgesehen davon, daß es Zweifel an md5 selber gibt und du statt einem hash-feld mit md5 auch drei mit md5, sha1 und ripmed160 nehmen kannst).

    Machen drei Hashs die sache nicht noch unsicherer? Immerhin 3 angriffsmöglichkeiten für den hash?

    Wenn ich jetzt frage welche Hash-methode ihr am sichersten haltet von den dreien, kriege ich dann eine halbwegs eindeutige antwort oder artet das dann so aus wie "Ist Mac OSX oder Windows besser"?

    EDIT:
    http://www.heise.de/security/artikel/Konsequenzen-der-erfolgreichen-Angriffe-auf-SHA-1-270648.html
    Wenn ich den artikel richtig verstehe sollte ich auf sha1 setzen da sowohl md5 als auch ripemd bereits geknackt sind?



  • Sqwan schrieb:

    Aber gut... wenn ich durch vermischen keinen vorteil habe kann ich tatsächlich auch die id anhängen.

    Falls Du die Designentscheidung jetzt fällen willst, daß ein einmal angelegter User seine ID nie mehr ändern wird. Ansonsten ein Auto-Inkrement- oder Zufallsfeld ohne Duplikate.

    volkard schrieb:

    (abgesehen davon, daß es Zweifel an md5 selber gibt und du statt einem hash-feld mit md5 auch drei mit md5, sha1 und ripmed160 nehmen kannst).

    Machen drei Hashs die Sache nicht noch unsicherer? Ja, schon. Aber Du kannst im Laufenden Betrieb entscheiden, daß md5 nichts taugt und droppen und nur noch die beiden anderen nehmen und wieder ein drittes dazunehmen und lernen lassen...

    volkard schrieb:

    Wenn ich jetzt frage welche Hash-methode ihr am sichersten haltet von den dreien, kriege ich dann eine halbwegs eindeutige antwort oder artet das dann so aus wie "Ist Mac OSX oder Windows besser"?

    Wikipedia schreibt "Da die Entwicklung von RIPEMD-160 offener war als die von SHA-1, ist es wahrscheinlicher, dass dieser Algorithmus weniger Sicherheitslücken aufweist. Da er jedoch weniger populär ist, haben weniger Kryptologen versucht, Schwächen zu finden, was wiederum die Wahrscheinlichkeit für unentdeckte Sicherheitslücken steigen lässt."
    Also man weiß es nicht. Folglich gehen die meisten religiös heran, halten das für sicherer, was schwieriger zu besorgen ist, was bei der Verwendung mehr Schmerzen verursacht.



  • Wobei diese erfolgreichen Angriffe noch richtig weit entfernt von der Aufgabe finde die Fragezeichen bei md5("???????????????????????????????????"."000000005"."?????")="a3cca2b2aa1e3b5b3b5aad99a8529074" und habe Glück, daß Dir nicht nur die Quasi-Unmöglichkeit gelingt, überhaupt eine Fragezeichenbelegung zu finden, sondern auch genau die, wo die 40 ersten Bytes, die der geheime salt1 sind.



  • @rest: Wie gedenkt ihr, dass ich sonnst meine user vor Bruteforce schütze? Das mit nach z.B. 10 versuchen für 1 stunde sperren ist keine schlechte idee. Damit würde man bruteforce natürlich stark verzögern.

    Admin-Accounts durch Doppellogin schützen. Nach erfolgreichem ersten Login noch einen zweiten Login anhängen (da natürlich andere Anmeldedaten verwenden)...

    LG



  • Die User müssen sich selbst vor Brutforce schützen, indem sie keine Passwörter aus dem Wörterbuch nehmen oder 123456.
    Was nützt es, den User für 60 Minuten zu sperren, wenn der Angreifer der Reihe nach die 20000 User abrödelt? Da darf er 333 Tests pro Sekunde machen, mehr als Apache/PHP/mysql schafft.
    Du müßtest machen, daß von dieser IP für 15 Sekunden keine Eingabe mehr als richtig beantwortet wird. Bringt aber nichts, wenn der Angreifer sich als Proxy ausgibt. Dann kannste es auch lassen.

    Also noch einfacher. Jede Passwort-Abfrage wird nur mit 1s Verzögerung beantwortet.



  • hash(misch(passwort, salt)) (wenn hash so etwas wie md5, sha1 oder ripemd ist) hat vorallem das Problem, dass das Verfahren zu schnell ist. Bei Passwortabfragen will man nämlich kein schnelles Verfahren! Sonst macht man es dem Angreifer zu leicht ein Rainbowtable zu generieren. Aus dem Grund werden Passwort-Verfahren extra langsam entwickelt. zB bcrypt. Ich würde auch eher dazu raten, dass man ein bekanntes Verfahren für Produktionscode einsetzt, wenn man sich nicht ausführlich mit dem Thema befassen will.

    btw. das finde ich zB an PHP so schlimm. Es vermittelt zwar einfach und flink in der Entwicklung zu sein. Aber dann haben die nicht einmal ein Standardpasswortverfahren in ihrer Bibliothek (obwohl die mit allem möglichen Blödsinn überflutet ist), obwohl so etwas doch oft gebraucht wird. Am Ende speichern die Entwickler die Passwörter dann doch im Klartext oder machen wenig effektive Dinge ala md5(passwort) oä. Aber das soll hier ja nicht in eine Diskussion abdriften, warum PHP so katastrophal ist.

    md5 collisions zu finden ist mittlerweile nur noch im Bereich von Minuten.


Anmelden zum Antworten