it-swarm.dev

Ist es sicherer, ein Passwort mehrmals zu hashen?

Ich habe ein paar Mal gelesen, dass es beim Speichern von Passwörtern empfehlenswert ist, die Zeichenfolgen zu verdoppeln (z. B. mit md5, dann sha1, natürlich beide mit Salzen).

Ich denke die erste Frage ist: "Ist das wirklich richtig?" Wenn nicht, dann entlassen Sie bitte den Rest dieser Frage :)

Der Grund, den ich frage, ist, dass ich auf den ersten Blick sagen würde, dass dies sinnvoll ist. Wenn ich jedoch darüber nachdenke, kann ich jedes Mal, wenn ein Hash erneut aufbereitet wird (möglicherweise mit etwas hinzugefügtem), nur sehen, dass sich die Obergrenze für die endgültige „Einzigartigkeit“ verringert ... mit der die Grenze in Beziehung steht die anfängliche Eingabe.

Lassen Sie es mich anders sagen: Wir haben x Anzahl von Zeichenfolgen, die beim Hashing auf y mögliche Zeichenfolgen reduziert werden. Das heißt, es gibt Kollisionen im ersten Satz. Ist es nicht möglich, dass vom zweiten zum dritten Satz dasselbe auftritt (dh Kollisionen im Satz aller möglichen 'y'-Zeichenfolgen, die im dritten Satz zum gleichen Hash führen)?

In meinem Kopf sehe ich nur einen "Trichter" für jeden Hash-Funktionsaufruf, "Trichter" einer unendlichen Menge von Möglichkeiten in eine endliche Menge und so weiter, aber offensichtlich arbeitet jeder Aufruf an der endlichen Menge davor und gibt uns eine nicht größer als der Eingang einstellen.

Vielleicht erklärt ein Beispiel meine Streifzüge? Nehmen Sie 'hash_function_a', das 'a' und 'b' den Hash '1' gibt, und geben Sie 'c' und 'd' den Hash '2'. Wenn ich diese Funktion zum Speichern von Passwörtern verwende, kann ich das Passwort 'b' verwenden, auch wenn das Passwort 'a' ist.

Nimm 'hash_function_b', das '1' und '2' den Hash '3' gibt. Wenn ich it als 'sekundären Hash' nach 'hash_function_a' verwenden würde, könnte ich selbst dann, wenn das Passwort 'a' lautet, 'b', 'c' oder 'd' verwenden.

Darüber hinaus verstehe ich, dass Salze verwendet werden sollten, aber sie ändern nichts an der Tatsache, dass wir jedes Mal, wenn wir 'x'-Eingänge auf' weniger als x'-Ausgänge abbilden. Ich glaube nicht.

Kann mir bitte jemand erklären, was ich hier vermisse?

Vielen Dank!

EDIT: für das, was es wert ist, mache ich das nicht selbst, ich benutze bcrypt. Und ich bin nicht wirklich besorgt darüber, ob es nützlich ist, Zyklen für einen Hacker zu verbrauchen oder nicht. Ich frage mich wirklich nur, ob der Prozess die "Sicherheit" unter dem Gesichtspunkt der Hash-Kollision verringert oder nicht.

43
Narcissus

Dies ist besser für security.stackexchange geeignet, aber ...

Das Problem mit

hash1(hash2(hash3(...hashn(pass+salt)+salt)+salt)...)+salt)

ist, dass dies nur so stark ist wie die schwächste Hash-Funktion in der Kette. Wenn beispielsweise Hash (der innerste Hash) eine Kollision ergibt, führt die gesamte Hash-Kette zu einer Kollision (nabhängig davon, welche anderen Hashes in der Kette enthalten sind).

Eine stärkere Kette wäre

hash1(hash2(hash3(...hashn(pass + salt) + pass + salt) + pass + salt)...) + pass + salt)

Hier vermeiden wir das Problem der frühen Kollision und generieren im Wesentlichen ein Salz, das vom Passwort für den endgültigen Hash abhängt.

Und wenn ein Schritt in der Kette kollidiert, spielt dies keine Rolle, da im nächsten Schritt das Kennwort erneut verwendet wird und für unterschiedliche Kennwörter ein anderes Ergebnis liefern sollte.

27
ratchet freak

Die Verwendung verschiedener Hashing-Algorithmen ist eine schlechte Idee - sie verringert die Entropie, anstatt sie zu erhöhen.

Unter der Annahme, dass Sie einen kryptografisch starken Hashing-Algorithmus und ein gutes Salz haben, wird durch mehrmaliges Anwenden von dieselbe Hash-Funktion der Hashing-Prozess rechenintensiver. Dies hat den Vorteil, dass andere Methoden zum Knacken des Kennwort-Hashs (Erraten, Wörterbuchangriffe, Regenbogentabellen usw.) fehlschlagen und der Angreifer zu Brute-Force-Techniken gezwungen wird, um jedes Kennwort zu testen, einfach weil Sie müssen die gleiche Hash-Funktion häufiger anwenden. Wenn also eine Hashing-Runde einen Monat Brute-Forcing erfordern würde, würde eine zwölfmalige Anwendung die geschätzte Zeit auf ein Jahr erhöhen.

Neuere Hashing-Algorithmen wie bcrypt bauen auf dieser Idee auf. Sie enthalten einen Parameter zur Steuerung der rechnerischen Komplexität des Hashs, sodass Sie ihn skalieren können, wenn die Hardware schneller wird. Wenn die Hardware um den Faktor zwei schneller wird, erhöhen Sie die Komplexität für die Kompensation und damit die Zeit, die erforderlich ist, um Ihren Hash zu erzwingen Hashes bleiben ungefähr konstant.

55
tdammers

Versuchen Sie nicht, Ihr eigenes Passwort-Hashing-Schema zu schreiben, es sei denn, Sie sind bereit, einen Kurs in Kryptographie und/oder Sicherheitstechnik zu belegen.

Sie sollten eine gut etablierte Implementierung von Passwort-Hashing verwenden, die wiederum eine Schlüsselableitungsfunktion ( KDF ) wie PBKDF2, bcrypt, scrypt oder das neuere Argon2 verwenden sollte .

Gute KDFs enthalten einen Workfaktor, normalerweise eine Reihe von Iterationen, um die Kosten für Offline-Angriffe zu erhöhen. Man könnte sagen, dass diese KDFs das Passwort mehrmals hashen und jedes Mal denselben Algorithmus verwenden. Es macht keinen Sinn, einen Mehrfachnachrichten-Digest-Algorithmus zu verwenden, wie von anderen hervorgehoben.

3
Erwan Legrand

Im Allgemeinen müssen Sie nicht mehr als einen Hashing-Algorithmus verwenden.

Was Sie tun müssen, ist:

Verwenden Sie Salz: Salz wird nicht nur verwendet, um Ihr Passwort zu verbessern sicherer Es wird verwendet, um Regenbogentabellenangriffe zu verhindern. Auf diese Weise wird es jemandem schwerer fallen, den Hash für Kennwörter, die Sie in Ihrem System speichern, vorab zu berechnen.

Verwenden Sie mehrere Interaktionen: Anstatt nur SHA (Passwort + Salz) zu machen, machen Sie SHA (SHA (SHA (SHA (SHA (... SHA (Passwort + Salz)))). Oder anders dargestellt:

hash = sha(password + salt)
for i=1 , i=5000, i++ {
    hash = sha(hash + salt);
}

Und schließlich wählen Sie eine gute Hashing-Funktion. SHA, MD5 usw. sind nicht gut, weil sie zu schnell sind. Da Sie zum Schutz Hash verwenden möchten, sollten Sie langsamere Hashes verwenden. Schauen Sie sich zum Beispiel Bcrypt , PBKDF2 oder Scrypt an.

edit : Versuchen wir nach den Beobachtungen, einige Punkte zu sehen (sorry, lange Erklärung, um zum Ende zu kommen, da dies anderen helfen könnte, nach ähnlichen Antworten zu suchen). ::

Wenn Ihr System sicher ist und niemand jemals Zugriff auf das gespeicherte Passwort erhalten wird, benötigen Sie keinen Hash. Das Passwort wäre geheim, niemand würde es bekommen.

Aber Niemand kann sicherstellen, dass die Datenbank mit den Passwörtern gestohlen wird. Stehlen Sie die Datenbank, haben Sie alle Passwörter. Ok, Ihr System und Ihr Unternehmen werden unter allen Konsequenzen leiden. Wir könnten also versuchen, dieses Passwortleck zu vermeiden.

[~ # ~] beachte [~ # ~], dass wir uns in diesem Punkt keine Sorgen um Online-Angriffe machen. Für einen Online-Angriff besteht die beste Lösung darin, nach falschen Passwörtern zu verlangsamen, das Konto nach einigen Versuchen zu sperren usw. Dabei spielt es keine Rolle, auf welche Weise Sie Ihr Passwort verschlüsseln, hashen, speichern usw. Bei Online-Angriffen geht es darum, die Passworteingaben zu verlangsamen.

Also zurück zum don't let them take my plain passwords Problem. Die Antwort ist einfach: Speichern Sie sie nicht als einfachen Text. OK habe es.

Wie vermeide ich das?

Verschlüsseln Sie das Passwort (?). Aber wie Sie wissen, können Sie es, wenn Sie es verschlüsseln, zurück entschlüsseln, wenn Sie den richtigen Schlüssel haben. Und am Ende haben Sie das Problem, wo Sie den Schlüssel verstecken können. Hum, nicht gut, da sie Ihre Datenbank haben, können sie Ihren Schlüssel bekommen. Ok, lass es uns nicht benutzen.

Ein anderer Ansatz: Lassen Sie uns das Passwort in etwas anderes umwandeln, das nicht rückgängig gemacht werden kann, und es speichern. Um zu überprüfen, ob das angegebene Kennwort korrekt ist, führen wir den gleichen Vorgang erneut durch und prüfen, ob die beiden transformierten Werte übereinstimmen. Wenn sie übereinstimmen = wurde das gute Passwort angegeben.

Ok, soweit so gut. Verwenden wir einen MD5-Hash im Passwort. Aber ... wenn jemand unseren gespeicherten Hash-Wert des Passworts hat, kann er viel Computerleistung haben, um den MD5-Hash jedes möglichen Passworts (Brute Force) zu berechnen, damit er das ursprüngliche Passwort finden kann. Oder schlimmstenfalls kann er alle MD5 aus allen Zeichenkombinationen speichern und das Passwort leicht finden. Machen Sie also viele Iterationen, das HASH (HASH (HASH ())) - Ding, um es schwieriger zu machen, weil es länger dauern wird.

Aber auch das kann umgangen werden, der Rainbow-Tisch wurde genau entwickelt, um diese Art von Schutz zu beschleunigen.

Verwenden wir also etwas Salz darüber. Auf diese Weise wird bei jeder Wechselwirkung das Salz erneut verwendet. Wenn Sie versuchen, Ihre Passwörter anzugreifen, muss die Rainbow-Tabelle erstellt werden, wenn Sie berücksichtigen, dass das Salz jedes Mal hinzugefügt wird. Und wenn er diese Regenbogentabelle generiert, da sie mit einem Salz generiert wurde, muss er erneut mit dem anderen Salz rechnen, sodass er einige Zeit für jedes Passwort (= jedes Salz) aufwenden muss. Salt erhöht nicht die Komplexität des Kennworts. Der Angreifer verliert nur Zeit beim Generieren der Rainbow-Tabelle. Wenn Sie für jedes Kennwort ein Salt verwenden, ist die Tabelle von einem Salt für ein anderes Kennwort unbrauchbar.

Und die Verwendung von mehr als einem Hash hat hier geholfen? Nein. Die Person, die einen bestimmten Regenbogenangriff erzeugt, kann ihn ohnehin mit einem oder mehreren Hashes erzeugen.

Die Verwendung von mehr als einem Hash kann zu einem Problem führen: Es ist so sicher wie der schwächste Hash, den Sie verwenden. Wenn jemand Kollisionen in einem Hash-Algorithmus findet, wird dieser Hash zu jedem Zeitpunkt des Iterationsprozesses ausgenutzt, um das Kennwort zu brechen. Wenn Sie also mehr Hashes-Algorithmen verwenden, gewinnen Sie nichts. Es ist besser, nur einen guten Algo zu wählen. und benutze es. Und wenn Sie jemals hören, dass es kaputt ist, überlegen Sie, wie Sie es in Ihrer Anwendung ändern werden.

Und warum bcrypt oder ähnliches verwenden (Sie sagen, Sie verwenden es): weil der Angreifer mehr Zeit damit verbringen muss, die Tabellen zu generieren. Aus diesem Grund hilft die Verwendung von MD5 + wait (3 Sekunden) nicht weiter: Der Angriff ist ohnehin offline, sodass der Angreifer die Tabellen ohne (3 Sekunden Verzögerung) generieren kann.

2
woliveirajr