Frage:
Ist mein benutzerdefinierter Passwort-Hashing-Algorithmus unsicher?
reggaemuffin
2014-09-12 12:56:21 UTC
view on stackexchange narkive permalink

Für alle meine Hobby-Webprojekte habe ich ein Anmeldesystem codiert, das diese Projekte gemeinsam nutzen. In diesen Projekten gibt es keine kritischen Daten. Die einzigen kritischen Daten können wiederverwendete Kennwörter sein. Deshalb versuche ich, Passwörter auf sehr sichere Weise zu hashen.

Mein aktueller Passwort-Hashing-Algorithmus ist nichts, was ich als wirklich sicher bezeichnen würde. Und als ich sah, dass PHP jetzt integriertes Hashing mit password_hash anbietet, dachte ich über einen Wechsel nach.

Meine Frage ist, was sind die Vorteile eines Wechsels für mich? Welchen zusätzlichen Schutz bekomme ich, welche Löcher repariere ich usw.? Und muss ich noch etwas tun, um es nicht extrem unsicher zu machen?

Ich möchte die Antworten als Lernerfahrung für mich selbst nutzen, damit ich sie anderen beibringen kann, die in meiner Position sind.

Mein aktueller Algorithmus (Pseudocode):

  Salt = "etwas Salz" 1000000 Mal wiederholen Passwort = Sha512 (Salz + Benutzername + Salz + Passwort)  

Ich weiß, dass meine Site anfällig für Timing-Angriffe ist, und die in PHP integrierten Funktionen würden dies beheben.

Was ist sonst noch offensichtlich unsicher?

Was auch immer Sie tun, lesen Sie [Wie man Passwörter sicher hasht?] (Http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846)
Es ist besser als nichts (ein großes Lob, wenn man zumindest über das Problem nachdenkt), aber im Allgemeinen ist pbkdf2 / bcrypt / scrypt mit anständigen Einstellungen immer besser als etwas, das man sich selbst ausgedacht hat.
TL; DR ** ja **, es ist unsicher. Rollen Sie nicht Ihren eigenen Hashing-Algorithmus
Er verwendet keinen eigenen Hashing-Algorithmus, sondern offensichtlich sha512. Meiner Meinung nach ist es ziemlich sicher, wenn Sie es nur 2 oder 3 Mal ausführen. Das Ausführen von 1000000 ist einfach nicht effizient.
-1
Die Antwort auf "Ist mein von einem Amateur allein entwickeltes Kryptosystem gegen mindestens einen Angriff von willkürlich vielen entschlossenen intelligenten Angreifern mit verfügbaren Ressourcen unsicher?" ist ja*. Die Details des Systems sind irrelevant.
"Ist mein Brauch _______ unsicher?" Fast sicher.
Siehe http://crypto.stackexchange.com/questions/959/strength-of-multiple-hash-iterations
Wenn Sie der Meinung sind, dass es nicht unsicher ist und den Stand der Technik verbessert, sollten Sie es an https://password-hashing.net/ senden. Wenn nicht, verwenden Sie etwas, das gut getestet und auf vorhandene Best Practices abgestimmt ist.
@Kostronor Nein. Es ist * nicht * einfach, diesen Algorithmus zu erzwingen, selbst wenn der Angreifer den Algorithmus kennen würde. Hinweis: Sie erhalten diese Laufzeit bei * einer * Funktionsausführung, erwarten jedoch, dass> 1000 Personen sie gleichzeitig ausführen würden, als Sie sehen würden, was ich mit effizient meine.
Sechs antworten:
Lucas Kauffman
2014-09-12 14:01:30 UTC
view on stackexchange narkive permalink

Für den Anfang haben Sie Ihren eigenen Passwort-Hashing-Algorithmus gerollt. Derzeit gibt es nur drei Kennwort-Hashing-Algorithmen, die als sicher gelten:

  • PBKDF2
  • scrypt
  • bcrypt

Sie iterieren und fügen ein Salz hinzu. Sie scheinen auch den Benutzernamen innerhalb des Algorithmus hinzuzufügen, was keinen Vorteil bringt, da Sie bereits ein Salt verwenden.

Was ich nicht von Ihrem Code abziehen kann und was sehr wichtig ist, ist die Länge Ihres Salzes und wie Sie es erzeugen. Ein Salt sollte niemals fest codiert, sondern sicher zufällig generiert werden, wenn das Passwort gehasht wird. Das Salt sollte innerhalb der Datenbank eindeutig und vorzugsweise global eindeutig sein, um die Identifizierung ähnlicher Passwörter in verschiedenen Datenbanken zu vermeiden (daher wird ein Benutzername nicht als gutes Salt angesehen).

Die Funktionsweise von PBKDF2 (die Ihrer Implementierung am nächsten kommt) besteht auch in der Verwendung eines HMAC, bei dem das zufällig generierte Salt der Schlüssel zur Berechnung des Nachrichtenauszugs ist, anstatt alles zusammenzufügen. PHPs password_hash verwendet den bcrypt-Algorithmus.

Um zusammenzufassen, was Sie durch die Verwendung eines Standardalgorithmus anstelle Ihres eigenen Algorithmus erzielen:

  • Sie generieren zufällige Salze
  • Sie verwenden einen standardisierten und sicheren Passwort-Hashing-Algorithmus
Ein weiterer Vorteil für die Verwendung einer integrierten Methode: Wenn der Algorithmus Fehler aufweist, werden Sie möglicherweise von einem Sicherheitsbulletin bemerkt, und Sie erhalten wahrscheinlich eine feste Version ohne viel Arbeit.
Mein aktuelles Salz ist ungefähr 32 Zeichen lang und wird nicht zufällig generiert. Es ist nur ein Teil des Legacy-Codes aus der Zeit, als Regenbogentabellen ein Problem darstellten. Der Benutzername war meine Idee, wie ich das Salz einzigartiger machen kann. Aber Sie haben Recht damit, dass es kein gutes Salz ist. Können Sie etwas näher darauf eingehen (oder mich mit vertrauenswürdigen Ressourcen verknüpfen, Crypto hat leider eine starke Meinung bei der Suche nach Vergleichen), welchen Algorithmus ich am besten auswählen kann? Meine Hashing-Funktion ist isoliert und kann leicht geändert werden.
PBKDF2 ist NIST- und FIPS-zugelassen. Die Verschlüsselung ist theoretisch stärker als die Verschlüsselung, jedoch weniger geprüft. In beiden Fällen verwendet die PHP-Funktion bcrypt, daher würde ich einfach die integrierte PHP-Funktion verwenden. Alle Kryptoressourcen finden Sie auf dieser Website (Suchschaltfläche oben). Suchen Sie nach den Antworten von Thomas Pornin.
@Lucas vielen Dank für Ihre Antwort, wird nach seinen Antworten suchen!
@LucasKauffman: Ermöglicht eine dieser Methoden, die Hash-Stärke eines vorhandenen Hash-Schlüssels zu erhöhen, ohne das ursprüngliche Passwort zu benötigen? Konzeptionell scheint dies möglich zu sein, wenn die Kennworttabelle eine Liste der Hashes enthält, die für ein Kennwort ausgeführt werden sollten, um einen bestimmten Wert zu erhalten. Das atomare Hinzufügen einer Hash-Methode zur Liste der Aktionen, das Einspeisen des erwarteten Ergebnisses durch diese Hash-Methode und das Speichern des Ergebnisses dieser Methode in der Datenbank sollte einen "stärker gehashten" Datensatz ergeben, ohne dass das ursprüngliche Kennwort erforderlich ist .
@supercat Ja, Sie können old_hash_func (Passwort) als "Passwort" für den verbesserten Hash verwenden, für alte Konten, die sich noch nicht angemeldet haben.
Eine weitere Sache, die Sie gewinnen, ist die Bequemlichkeit. Die Funktion password_hash () packt alle erforderlichen Parameter in den resultierenden Hash-Wert (Salt / Kostenfaktor / Algo). Diese Zeichenfolge können Sie in einem einzelnen Datenbankfeld speichern.
"Als sicher angesehen" - von wem? Zitieren erforderlich.
Gilles 'SO- stop being evil'
2014-09-12 18:10:59 UTC
view on stackexchange narkive permalink

Unter der Annahme, dass etwas Salz tatsächlich nie wiederholt wird, ist dies eine akzeptable Methode zum Hashing von Passwörtern. Es kombiniert die drei wesentlichen Elemente: keine Wiederherstellung des Hash aus den Passwörtern (dank der Verwendung von SHA-512), intrinsische Langsamkeit (aufgrund der hohen Anzahl von SHA-512-Iterationen) und ein einzigartiges Salz.

Das Salt muss global eindeutig sein: Es darf nicht zum Hashing anderer Kennwörter, zum Hashing des gleichen Kennworts bei einer Kennwortänderung oder in der Kennwortdatenbank eines anderen Benutzers verwendet werden. Die Verletzung der Eindeutigkeit ist nicht unbedingt kritisch, aber je mehr es passiert, desto einfacher wird es für einen Angreifer. Im Extremfall ist das „Salz“ konstant, es ist kein Salz und Ihre Passwort-Hashing-Methode ist schrecklich. Wenn es sich um den Benutzernamen oder die Datensatz-ID handelt, ist dies immer noch schlecht, da mehrere Datenbanken einen kleinen Satz Salze gemeinsam nutzen.

Sie sollten jedoch eine Standard-Hashing-Methode verwenden. Möglicherweise liegt eine Sicherheitslücke in Ihrer Methode vor, die wir übersehen haben, weil sie auf subtilen Details beruhte. Möglicherweise haben Sie bei der Implementierung einen Fehler gemacht. Aus diesem Grund ist eine gut unterstützte Implementierung mit Sicherheitsupdates vorzuziehen. Im Algorithmus kann eine Schwäche entdeckt werden. Auch hier ist es besser, eine gut unterstützte Implementierung zu verwenden, deren Implementierer über Kryptografienachrichten auf dem Laufenden bleibt und den Algorithmus bei Bedarf ändert.

Sie müssen darauf achten, die Anzahl der Iterationen mit der Zeit zu erhöhen vergeht und Computer werden schneller. Ein gutes

Lesen Wie man Passwörter sicher hasht? (ja, alles). Bcrypt ist PBKDF2 etwas überlegen, da es resistenter gegen GPU-basierte Angriffe ist. PBKDF2 folgt denselben Prinzipien wie Ihr benutzerdefinierter Hash. Die Verwendung von PBKDF2 ist derzeit keine große Sicherheitsanfälligkeit, ich würde jedoch empfehlen, auf bcrypt oder scrypt umzusteigen.

Bristol
2014-09-12 18:29:44 UTC
view on stackexchange narkive permalink

Ihr Algorithmus ist meilenweit besser als viele "Homebrew" -Algorithmen. Der Grund, warum ich immer noch zu einem standardisierten wechseln würde, ist, dass Sie von all der Prüfung profitieren, die diese Standards erhalten haben, die Ihre eigene Konstruktion nicht hat.

Gibt es definitiv keinen Fehler in Ihrer Konstruktion, der dies zulässt eine triviale Pause? Wenn nicht, sind Sie sicher, dass Ihr Algorithmus nicht für einen beschleunigten Brute-Force-Angriff mit massiv parallelen GPUs anfällig ist? Könnte es eine optimierte Form des Regenbogentabellenangriffs auf Ihren speziellen Algorithmus geben?

Die Antwort lautet wahrscheinlich nein, nein und nein, aber mehr Leute haben sich mit PBKDF2 befasst als mit Ihrem Algorithmus, sodass es weniger wahrscheinlich ist, dass es etwas gibt böse, dass bisher niemand entdeckt hat. Dies ist ein heuristisches Argument, aber vergessen Sie nicht, auch wenn Ihr Algorithmus gut ist (und für mich sicherlich nicht dumm aussieht), gibt es Hunderte anderer Leute, die ihre eigene Krypto implementiert haben, die sich als schrecklich kaputt herausstellte . Deshalb sagen wir in der Regel, rollen Sie nicht Ihre eigenen.

Es ist der gleiche Grund, warum wir nicht jedem erlauben, elektrische Hochspannungsanschlüsse zu installieren und zu modifizieren: Die Qualifikation eines Elektrikers reicht nicht aus. Es schützt Sie auf magische Weise vor Stromschlägen, aber es bedeutet, dass Sie hoffentlich genug Erfahrung in der Gegend haben. Tun Sie nichts zu Dummes, als einen zufälligen Draht zu ergreifen und zu sehen, ob er unter Spannung steht oder nicht.

Nixe Beispiel mit dem Elektriker!
nobody
2014-09-12 21:47:01 UTC
view on stackexchange narkive permalink

Ein Nachteil beim Einfügen des Benutzernamens als Teil des Salt ist, dass Sie einen Benutzer nicht umbenennen können (z. B. administrativ), ohne einen neuen Kennwort-Hash zu generieren (was bedeutet, dass Sie ein neues Kennwort auswählen und dem Benutzer mitteilen müssen, oder Fragen Sie den Benutzer nach seinem aktuellen Passwort.

Hinweis: Fragen Sie den Benutzer niemals außerhalb der Standard-Anmeldeseite (n) nach seinem aktuellen Passwort.
kasperd
2014-09-13 13:48:57 UTC
view on stackexchange narkive permalink

Ich sehe einige Probleme mit Ihrem Ansatz.

  • Sie scheinen einen konstanten Salzwert zu verwenden. Es ist sicherer, für jedes Kennwort ein neues Salt zu generieren.
  • Das Einfügen des Benutzernamens in das Salt kann problematisch sein. Wie Andrew betont hat, können Sie einen Benutzer nicht umbenennen. Es mildert das Problem teilweise mit einem konstanten Salz. Das Problem wird dadurch jedoch nicht vollständig gemindert, da sich der Benutzername nicht jedes Mal ändert, wenn sich das Kennwort ändert.
  • Sie geben das Kennwort nur in die erste Iteration ein. Es besteht das theoretische Risiko, dass die Entropie aus dem Kennwort beim Iterieren langsam verschwindet.
  • Eine hohe Iterationszahl kann Sie für DoS-Angriffe anfällig machen.

Die Iterationszahl ist doppelt so hoch Schwert. Eine hohe Anzahl von Iterationen macht Ihren Server anfällig für DoS-Angriffe. Eine niedrige Iterationszahl macht Ihre Kennwortdatenbank anfällig für Offline-Brute-Force-Angriffe. Die einzige Möglichkeit, sich vor beiden zu schützen, besteht darin, einen Teil der Berechnung auf den Client zu verlagern. Dies erfordert jedoch Code auf dem Client. In einem Webdienst könnte ein solcher Code per Javascript bereitgestellt werden, aber Javascript ist nicht so schnell wie nativer Code, sodass der Angreifer einen Vorteil gegenüber der legitimen Verwendung hätte.

Ihre Erinnerung an DOS ist wirklich gut! Beim Umschalten dachte ich, die Funktion einfach 5 Sekunden laufen zu lassen, um extrem sicher zu sein. Aber gut zu wissen, dass dies auch ein Angriffsvektor werden könnte, danke!
aaaaaaaaaaaa
2014-09-13 16:03:55 UTC
view on stackexchange narkive permalink

Zunächst einmal haben Sie aus Sicht der Passwortsicherheit einen ziemlich guten Algorithmus.

Ihr Salt ist technisch gesehen kein Salt, da es für jeden Benutzer gleich ist, aber wenn Sie es mit dem kombinieren Benutzername Es ist eine einzigartige Information, so dass Sie die vollständige Sicherheit eines Salzes haben. Wenn Ihre "etwas Salz" -String kryptografisch stark ist (mindestens 64 Bit Entropie), funktioniert sie auch als Pfeffer.

Aus praktischen Gründen würden Sie dies tun Im Allgemeinen möchten Sie vermeiden, den Benutzernamen im Kennwort-Hash-Algorithmus zu verwenden, da dies das Ändern des Benutzernamens erschwert und Sie für den Vorgang das Nur-Text-Kennwort benötigen. Ein dediziertes Salt ist einfacher zu verwalten.

Eine Million Hashing-Iterationen scheinen etwas übertrieben zu sein. Es könnte leicht zum Engpass einer geschäftigen Website werden. Ich würde es auf ein Niveau reduzieren, das Sie tun können Mindestens 1000 Kennwort-Hashes pro Sekunde.

Stellen Sie außerdem sicher, dass Sie über einen Mechanismus zum Drosseln von Anmeldeversuchen verfügen. Wenn ein Angreifer einfach 1000 Anmeldeversuche pro Sekunde brennen kann, kann er schnell viele schwache Kennwortbenutzerkonten stehlen oder er kann das Passwort-Hashing als Denial-of-Service-Waffe verwenden.

Ich glaube, es gibt keine allgemein anerkannten Best Practices für die Drosselung von Anmeldungen, außer dass keine Drosselung die schlechteste Lösung ist .

Login-Drosselung ist ein guter Punkt, danke dafür!


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...