PHP Verschlüsselungen in PHP

nein muss es nicht. die ausgangsbasis (=eingabe) ist immer noch die gleiche. per bruteforce muss somit nur das erste herausgefunden werden, da der zweite hash vom ersten abhängig ist. am einfachsten kann man das wohl so erklären: nach dem hände waschen, trocknest du dir die hände ab und zwar automatisch. genau das gleiche machst du nun hier im übetragenen sinne. wenn du das passwort oder was auch immer herausgefunden hast, wird dieser wert gehasht. dieser hash ist immer der gleiche (wenn wir vom passwort ausgehen). wenn du dies nun erneut hashst, dann hast du einen hash vom hash, welcher genauso immer der gleiche ist und vom 1. abhängig ist.

schwer zu erklären, vielleicht mal ein konkretes beispiel:
der (md5-)hash von "test" ist "098f6bcd4621d373cade4e832627b4f6". der hash vom hash ist "fb469d7ef430b0baf0cab6c436e70375". und nun der hash vom hash von test ist identisch zum hash vom hash "fb469d7ef430b0baf0cab6c436e70375". es bringt für die sicherheit also nichts, wenn man 2 mal hasht (außer erhöhte rechenlast). du könntest den hash nun 100 mal erzeugen, das ergebnis bleibt immer das gleiche, da die ausgangsbasis (das passwort) immer die gleiche ist und keine veränderung selbst intern vorgenommen wird. genauso bringt es nichts wenn du md5(sha1('abc')) anwendest, da dies genau aufs gleiche hinaus geht (auch md5('test'+sha1('abc')) bringt nichts).

rainbowtables umgeht man so auch nicht, sondern nur durch salted hashes (wie schon erwähnt wurde). salted hashes sind kurz gesagt hashes, in denen ein zufälliger, statischer, selbst ausgedachter term mit in den hash hinzugefügt wird. unbedachte seiten z.b. verwenden für den login lediglich einen "normalen" md5 hash vom passwort (md5('abc')), wodurch es hier möglich ist, durch rainbow tables zugriff zu einem x beliebigen nutzer zu erlangen. salted hashes realisierst du ganz einfach und ohne mehraufwand durch folgende anweisung: md5( 'dies wird ein salted hash, welcher in keiner rainbowtable zu finden sein wird. dabei bin ich mir sicher. ' + $passwort );. hierbei bezweifle ich schon, dass dieser hash irgendwo in einer rainbowtable gefunden werden kann. besser als solch ein zusatz, wäre es, ein definitiv sicheres passwort zu nehmen (sagen wir mal ein string mit groß- und kleinschreibung, zahlen und sonderzeichen) plus das passwort in einer annehmbaren großen länge. konkretes beispiel: md5( 'M!+fmfX4u+PFXv"&$8ZpikRFHegs:M-d' + $passwort );. hierbei müsste erst das erste "passwort" herausgefunden werden und zugleich das zweite (eigentliche) passwort ohne den zusatz. selbst wenn er das zweite, evtl. einfache passwort herausgefunden hätte, könnte er durch das erste definitiv sichere passwort, keinen zugriff zum system erlangen.

und nebenbei: md5( 'salted hash' + md5( 'test' ) ) ist nicht gleich md5( 'salted hash' + 'test' )!

ps: wenn es jemand besser erklären kann, dann schreibt drauf los. hab da immer so ein problem mit etwas auf einfache weise zu verdeutlichen. ;)
 
Gobble-G schrieb:
Es bleibt dennoch dabei: für eine ordentliche Ver- und Entschlüsselung sind Hashes nicht geeignet.

Zum x-ten mal, sie sind ja auch garnicht dafür gedacht :rolleyes:
claw hat es schon relativ gut erklärt.

Wäre ja lustig, wenn ich meine Festplatte mit md5 hashen könnte und danach aus den paar Zeichen wieder die vollen 250 GB entschlüssen könnte.
 
@claW.:
Irgendwie kapiere ich es nicht ;)

Nehmen wir doch einmal das:
Passwort = geheim (im folgenden a) genannt)
Hash von geheim = e8636ea013e682faf61f56ce1cb1ab5c (im folgenden b) genannt)
Hash vom Hash von geheim = 68b2073eea35186b9e109578e3b9c3ba (im folgenden c) genannt)

Und nehmen wir gerade einmal das Beispiel: Ein Forum wo man sich einloggt.
Im Forum wird ja per PHP aus a) c) gemacht und in die Datenbank als Passwort gespeichert.
Beim einloggen wird das gleiche gemacht, also a) zu c), und abgegleichen, ob die Hashes (der beim einloggen und der in der Datenbank) gleich sind.
Also um sich einloggen zu können muss man a) wissen.

So, wenn ich nun ein Hacker wäre und irgendwie in der Datenbank an "c)" herankommen würde, dann würde bei Brutforce irgendwann b) rauskommen. Mit b) kann ich ja aber nichts anfangen, und somit brauche ich NOCHMALS lange Zeit um von b) auf a) zu kommen. -> Bruteforce braucht 2 Schritte (c) -> b); b) -> a)), um auf das Passwort a) zu kommen.
Damit braucht ein Brutforce-Angriff die bis zu doppelte Zeit.

Und diese Rainbow-Tables umgeht man damit auch, da diese ja nur einmal gehaste Werte gespeichert haben. Beispiel-Seite.
b)->a) hat diese Datenbank gespeichert, c)->a) nicht.

Du musst ja davon ausgehen, dass ein Hacker den Hash c) hat.
Und um von c) auf a) zu kommen braucht man 2 Brutforce-Attacken.

Wenn man hingegen nur einmal verschlüsselt, also b) in der Datenbank hat, braucht man nur eine Attacke.

Daher sollte 2(3,4,..X)maliges verschlüsseln insofern sicherer sein, dass man doppelt (3fach,4fach,..Xfach) soviele Bruteforce-Atacken und somit doppelt (...Xfach) soviel Zeit benötigt, um den Hash per Bruteforce zu "knacken" und auf das ausgangspasswort a), welches man benötigt, zu kommen.

Wo ist mein Denkfehler ? Gerade jetzt einmal beim Beispiel Forum:
PHP:
$hash = md5(md5($passwort));
//speichere $hash in Datenbank
PHP:
// hole $hash aus der Datenbank
$vergleichen = md5(md5($eingabe_des_Benutzers_im_Passwortfeld_beim_einloggen));
IF ($vergleichen == $hash) {
// tu dich einloggen
}
So in etwa. Damit ich mich einloggen kann, muss ich in das Passwortfeld beim einloggen das richtige Passwort a) eingeben. Wenn ich b) eingeben würde, könnte ich mich nicht einloggen. -> Ich brauche a).
Und um von c) auf a) zu kommen brauche ich 2 Bruteforce-Attacken ;)
 
Zuletzt bearbeitet:
michi12 schrieb:
Irgendwie kapiere ich es nicht ;)
noch mal kurz:

du hast genau eine ausgangsbasis. wenn du diese basis herausbekommst, fällt alles in sich zusammen und du kommst an alles heran.

md5(md5(md5(md5($passwort)))) nutzt so viel wie verpacken(verpacken(verpacken(verpacken($apfel)))). eine verpackung reicht um es haltbar zu machen, weitere sind überflüssig und material-, sowie zeitverschwendung.

wenn du nun also md5(md5($foo)) machst, ist nur $foo selbst variabel. alles andere ist statisch und irrelevant. wenn du nun $foo herausbekommst, ist die logische schlussfolgerung, dass der darauffolgende md5() der selbe ist. wenn du $foo nicht herausbekommst, kommst du nicht an die daten.

vielleicht von oben noch mal das beispiel: verpacken(verpacken(verpacken(verpacken($glas)))) nutzt genauso wenig, da wenn irgendwo etwas schweres liegt oder irgend etwas mit großer wucht auftrifft, ist das glas hinüber. du müsstest also ein anderes mittel hinzugeben, welches die verpackung innerhalb stabilisiert, damit es nicht bei jedem konflikt zerbricht. also nimmst du irgend etwas hartes, schwer verformbares (kurz gesagt metall), mit welchem du die glasscheibe stabilisierst. analog dazu wäre dies der salted hash.

deine antwort mit den salted hashes erübrigt sich somit, da wenn du $foo herausbekommst, die restlichen hashes so oder so übereinstimmen müssen (begründung siehe oben). selbst wenn dies immun gegen rainbow tables machen sollte, gegen bruteforce ist es noch lange nicht immun und dies ist wohl der schwerwiegendere punkt. denk dabei mal ein paar jahre voraus, wo bruteforce evtl. nur noch sekunden bräuchte um 2^128 keys zu generieren. das ganze system sackt einfach so in sich zusammen, als wäre es eine umgekehrte pyramide. nimmst du die basis weg (der unterste stein), nimmt es den rest mit und ist somit kompromitiert.
 
Ok. Insofern hast du natürlich recht.

Aber doppeltes verschlüsseln ist aus heutiger Sicht insofern sicherer, als das Bruteforce länger braucht, um zur Ausgangsbasis zu kommen.

Bei einmal gehasem Wert braucht Bruteforce 1 Attacke, um auf das Passwort zu kommen.
Bei zweimal gehasem Wert braucht Bruteforce 2 Attacken, um auf das Passwort zu kommen.
Bei dreimal gehasem Wert braucht Bruteforce 3 Attacken, um auf das Passwort zu kommen.
usw.

Das sehe ich doch richtig, oder ?
 
Zurück
Oben