Theorie: Hash und Salt

ripuli-6

Lt. Junior Grade
Registriert
März 2005
Beiträge
273
Moin!

Ich schweife gerade mit meinen Gedanken ab und bin dabei auf das Thema Passwortsicherheit gekommen. Ich programmiere größtenteils in PHP, aber das Thema ist eher theoretischer Natur. Ich will auch gar nicht die Vor- und Nachteile von Salt in Passwörtern erörtern, sondern dessen Anwendung.

Ein Login-Beispiel dazu:
Das Script erstellt einen Hash-Wert vom Benutzernamen und nimmt diesen Hash und packt ihn ans Ende des Passworts. Dann wird dieser String gehasht und dieser Hash mit dem Hash Wert in der Datenbank abgeglichen.

Natürlich wurde der Wert in der Datenbank ähnlich ausgeführt.

Liege ich falsch mit der Annahme, dass ich jetzt einen recht sicheren Hash-Wert für das Passwort in der Datenbank habe? Denn im Grunde geht es ja darum bei einem Einbruch in meine Datenbank, die Passwörter für den Angreifer unbrauchbar zu machen. Und mit dieser Methode gibt es kein Salz, das irgendwo gespeichert werden muss, weil ich die benötigten Daten dafür jedes Mal erst generiere und das Salz ist für jedes Passwort individuell.
Natürlich bringt das nichts, wenn der Angreifer auch Zugriff auf meinen Quellcode hat (in dem Falle, wo der Quellcode offen liegt, zB PHP), denn dann weiß der Angreifer auch, wie die Passwörter gesalzen sind.

Liege ich mit meinen Überlegungen richtig oder habe ich fundamentale Dinge übersehen?
 
im grunde liegst du mit deinen überlegungen schon richtig. das hilft aber nur, wenn du deinen quellcode leichter schützen kannst als die datenbank vor fremdzugriff. du hast ja eigentlich bloß den salt von der datenbank in deinen quelcode verschoben.

darüber hinaus, wenn ich zugriff auf die datenbank hätte und finde keine salt-einträge, dann wäre der loginname mein erster kandidat für ein salt ;) mein zweiter das datum der account erstellung.
 
Hallo!

In deinem Fall verwendest du einen dynamischen Salt und deshalb ist es fast unmöglich dafür Rainbowtables zu erstellen.

Allerdings, wenn jemand root Zugriff auf deinen Mysql Server hat, dann hat er auch meistens Zugriff auf den Webserver und sieht, dass du einen hash vom Benutzernamen machst und alles war für die Katz.

Prinzipiell verwenden wir folgende Grundsätze: md5 nicht mehr verwenden oder nur noch mit Salt wenn es unbedingt sein muss. Dafür lieber sha256 verwenden, da noch schnell genug und sicher genug.

Mfg
 
Danke für eure Antworten!

@dese Nunja, ich könnte ja den Salt noch zusätlich absichern, indem ich doppelte hashe oder nur einen Teil vom HAsh verwende oder oder, aber prinzipiell liegt es dann am Programmierer, wie sicher der Salt-Wert ist und ich bezweifle, dass ein Hacker weitermachen würde, wenn ein Hash des Benutzernamens oder des Datums nicht helfen würde, denn dann gäbe es schließlich unendliche Möglichkeiten.

@agrundne md5 nehme ich schon ewig nicht mehr, aber der Hinweis ist schon sehr sinnvoll :) Natürlich gehen meine Überlegungen davon aus, dass ein Angreifer nicht an Quellcode kommt, denn dann ist das ganze Sicherheitssystem eh komprommitiert, zum Beispiel durch einen extra DB-Server und zusätzlich abgesichertem Webserver.
 
nun ja, ich sagte ja schon: im grunde sind deine überlegungen richtig. wende den salt nicht-trivial an und wenn du annimst, dass dein quellcode sicher ist, dann passt das. aber das ist ohnehin alles nur ein bonus. die verwendete hashfunktion trägt ja ohnehin die "hauptlast".

ein bisschen salt gegen faule user ;) ist aber durchaus hilfreich.
 
Wenn du davon ausgehst, dass dein Script sicher ist, müsstest du aber auch davon ausgehen, dass deine Datenbank sicher ist und die ganze Theorie mit Salts zum Erschweren des Findens der Klartext-PWs hat sich erübrigt.
 
Selbst wenn der Hacker an den Salt kommt ist ein Salt noch immer sinnvoll.
Denn dann muss er sich Tabellen für die Hash werte generieren.

Es gibt ja Datenbanken mit ergebnissen.
Die allerdings nicht für eine größere Länge funktionieren.
 
Funart schrieb:
Selbst wenn der Hacker an den Salt kommt ist ein Salt noch immer sinnvoll.
Denn dann muss er sich Tabellen für die Hash werte generieren.

natürlich, die Werte zu salzen ist immer sinnvoll, nur die Grundannahme von ripuli-6 war eben schon widersprüchlich, dass ein Teil sicher sein soll, der andere aber nicht. Bis auf sehr wenige Ausnahmen wird so etwas eben nicht zutreffen.



am besten ist sowieso:
PHP:
sha512($pw . $usersalt . $appsalt)
also ein user-spezifischer Salt der auch in der Datenbank abgespeichert wird und zusätzlich ein Anwendungsspezifischer Salt, der im PHP-Script ist.
  • wird Datenbank kompromittiert aber nicht Script: Anwendungs-Salt stellt weitere Sicherheit dar
  • wird Anwendung kompromittiert aber nicht die Datenbank: Hacker kennt die Hashes gar nicht :lol:
  • wird beides kompromittiert (Regelfall): kein Schutz möglich, aber der beschriebene Ansatz stellt wenigstens sicher, dass für jeden User ein einzelner Brute-Force Angriff gemacht werden muss und keine Rainbow-Tabellen möglich sind
 
Sicherlich ist die das Berechnen von Hash-Werten nicht allzu ressourcenfressend, aber wenn ich eine kompilierte Anwendung habe und ergo den Quellcode überhaupt nicht mehr nachverfolgen kann, sollte es doch unmöglich sein, die Applikations-Salt herauszufinden, richtig?

Für Php und andere Scriptsprachen, die zur Laufzeit kompiliert werden ist aber sicherlich Ice-Breakers Ansatz besser als meiner.

Wenn ich die Ergebnisse aber nun zusammenfasse, dann muss konstatiert werden, dass Salt in welcher Weise auch immer lediglich Rainbow-Table-Attacken unmöglich macht, aber keinen vollständigen Schutz bietet.
 
Am sichersten ist es, eine Hash-Funktion zu verwenden, die langsam ist. Damit werden Brute-Force-Attacken möglichst erschwert. Weitere Infos hier: http://codahale.com/how-to-safely-store-a-password/

ripuli-6 schrieb:
Sicherlich ist die das Berechnen von Hash-Werten nicht allzu ressourcenfressend, aber wenn ich eine kompilierte Anwendung habe und ergo den Quellcode überhaupt nicht mehr nachverfolgen kann, sollte es doch unmöglich sein, die Applikations-Salt herauszufinden, richtig?
Selbst wenn jemand nur an deinen kompilierten Code kommt, kann er ja mit einem Disassembler/Debugger rausfinden, welchen Salt du verwendest.
 
du könntest natürlich auch den benutzernamen nach einen bestimmten algorithmus zerlegen und "gewürfelt" zusammenbaun und den als salt hernehmen
würde das ganze gegen reine Datenbankübernahmen nochmal extrem sicherermachen

jedoch hilft das auch nur wenn dein webserver clean is und der quellcode unzugänglich
evtl deinen code extrem cryptisch schreiben verhindert wiederrum das ein bruchteil weniger in der lage ist deine passworter auszuspähen

ansonsten hat cx01 schon recht
 
ripuli-6 schrieb:
aber wenn ich eine kompilierte Anwendung habe und ergo den Quellcode überhaupt nicht mehr nachverfolgen kann, sollte es doch unmöglich sein, die Applikations-Salt herauszufinden, richtig?
man kann deine Anwendung immernoch dekompilieren (Disassembler).
Dein Schutz ist also nur "Security through Obscurity"

ripuli-6 schrieb:
Wenn ich die Ergebnisse aber nun zusammenfasse, dann muss konstatiert werden, dass Salt in welcher Weise auch immer lediglich Rainbow-Table-Attacken unmöglich macht, aber keinen vollständigen Schutz bietet.
es gibt keinen vollständigen Schutz

cx01 schrieb:
Am sichersten ist es, eine Hash-Funktion zu verwenden, die langsam ist. Damit werden Brute-Force-Attacken möglichst erschwert. Weitere Infos hier: http://codahale.com/how-to-safely-store-a-password/
In der Theorie stimme ich dem Autor vollkommen zu in der Praxis ist es aber einfach unwirtschafltich z.B. auf einem Server bcrypt für solche Stellen zu verwenden, da vielzuviel Rechenleistung verbraten wird, die man anderweitig benötigen könnte.
Wenn man natürlich absolute Sicherheit benötigt ist es garantiert sinnvoll, aber nicht als General-Purpose-Hashing.
 
ice-breaker schrieb:
In der Theorie stimme ich dem Autor vollkommen zu in der Praxis ist es aber einfach unwirtschafltich z.B. auf einem Server bcrypt für solche Stellen zu verwenden, da vielzuviel Rechenleistung verbraten wird, die man anderweitig benötigen könnte.
Wenn man natürlich absolute Sicherheit benötigt ist es garantiert sinnvoll, aber nicht als General-Purpose-Hashing.

Ob das Einloggen jetz 1µs oder 1ms dauert, macht für die Serverlast keinen nennenswerten Unterschied (ausser du hast tausende Logins pro Sekunde).
 
Idealerweise liegen ja DB und PHP-Executor nicht auf dem selben Rechner oder aber zumindest in verschiedenen chroots. (chroot ist eigentlich immer Pflicht, wenn einen nicht gerade der Hoster gängelt)

Selbst wenn man seinem Code traut, verwendet man immernoch eine unterliegende Codebasis, die angreifbar sein kann. Wenn man jetzt z.B. eine SQL-Injection durchkriegt (z.B. kaputte Unicode-Library, Payload wird nicht entdeckt und geht bis zur DB) bzw. eine der beiden Komponenten kompromittiert, hat man trotzdem nur die gesalzenen Passwörter.
 
wenn jemand in den Server rein will, dann schafft er es auch, von daher sehe ich die Systeme immer als komprimitierbar an und wenn es eine Schwachstelle im Betriebssystem direkt ist.
Die einzige Ausnahme bilden Systeme die nicht per Netzwerk verbunden sind und die Datenkommunikation über eine serielle Schnittstelle, USB oder ähnliches stattfinden.
 
Zuletzt bearbeitet:
Zurück
Oben