Frage:
Sollten Passwörter automatisch zurückgesetzt werden, wenn sich die zugrunde liegende Methode ändert
Crazy Dino
2016-03-21 19:03:57 UTC
view on stackexchange narkive permalink

Ich bin derzeit Ingenieur in einem Projekt in der Entwicklungsphase. Ein 'Modul' in diesem Projekt bietet die Möglichkeit zur Benutzerauthentifizierung / -autorisierung. Es ist jedoch zu unserer Sorge gekommen, dass der Passwort-Hashing-Algorithmus möglicherweise nicht dem Cop entspricht (auch bekannt als nicht BCrypt). (Das Schreckliche ist nicht ganz sicher, was es ist und woher es kommt!)

Dies muss sich offensichtlich ändern und der Patch wird geplant. Wir müssen natürlich alle unsere Testbenutzer aktualisieren, da ihre Passwörter die alte Hashing-Methode verwenden, was kein großes Problem darstellt. Alle unsere Demo-Benutzer werden beim Erstellen automatisiert, sodass das Skript aktualisiert wird. Die nächste Frage ist jedoch, was passiert, wenn es sich um ein Produktionssystem mit aktiven und veralteten Benutzern aller Art handelt. Was wäre die beste Vorgehensweise?

  1. Erzwingt automatisch ein Zurücksetzen des Kennworts für jeden Benutzer? Dadurch wird jeder Benutzer darüber informiert, dass sein Kennwort geändert wurde. Dies kann zu Fragen / Verwirrung führen und den Verdacht auf eine Sicherheitsverletzung aufkommen lassen. Möglicherweise werden weitere Fragen gestellt, die von den Stakeholdern der Website möglicherweise nicht unbedingt beantwortet werden können.
  2. Aktualisieren Sie die Datenbank, um zu kennzeichnen, ob es sich um die neue oder die alte Methode handelt. Sobald ein Benutzer authentifiziert wurde, aktualisieren Sie sein Kennwort in der DB mit. Erfordert ein wenig Logik im Dienst und der Übergang wird für jeden vorhandenen Benutzer scheinbar unmöglich sein. Das Problem besteht darin, dass bei einem Verstoß möglicherweise zwei Methoden angewendet werden. Wenn sich herausstellt, dass die weniger sichere Methode so unsicher ist, kann sie offensichtlich beschädigt werden.
  3. Alle Kennwörter zurücksetzen, Verwenden einer BCrypted-Version des vorhandenen Hash. Kennzeichnen Sie es als den alten Stil, sodass bei erfolgreicher Authentifizierung nur ein Hash des Kennworts und kein Hash eines Hashs beibehalten wird.
  4. ol>
Es gibt eine Abstimmung für "hauptsächlich meinungsbasiert", mit der ich nicht einverstanden bin: Hier gibt es solide, objektive Dinge zu sagen.
Ist der alte Algorithmus reversibel? Ethische Fragen für einen Moment ignorieren; Wenn der alte alte Algorithmus defekt und verständlich genug ist, um die ursprünglichen Kennwörter wiederherzustellen, ist es möglich, Benutzerdatensätze auf den neuen Algorithmus zu aktualisieren, ohne dass sich die Benutzer anmelden, und sie wären nicht klüger. Nur ein Gedanke!
@GreatSeaSpider Selbst wenn sie ungesalzenes MD5 verwenden würden, würde es Monate dauern, bis das Kennwort aller Benutzer geknackt ist - möglicherweise viele Monate, wenn Benutzer zufällige Kennwörter mit 32 Zeichen verwenden. Das ist eine Menge Geld für Server und Strom. Auf jeden Fall billiger, so etwas wie 2. oder 3 zu machen.
Bei näherer Betrachtung. Es scheint PBKDF2 zu verwenden, was durchaus akzeptabel zu sein scheint (der betreffende Entwickler kauft für den Rest der Woche immer noch Kuchen, da dies nicht offensichtlich war!). Ich denke immer noch, dass der Großteil meiner Frage "Was ist zu tun, wenn Kennwortspeicher-Hashes geändert werden?" Für zukünftige Referenz für andere Benutzer gültig ist.
Nur laut denken: Wäre es sinnvoll, ein Übergangsfenster zu definieren? Definieren Sie eine zukünftige Zeit (_end of support_ date), nach der jedes mit dem alten Schema gespeicherte Kennwort zurückgesetzt wird, und aktivieren Sie eine Anmeldelogik, in der das Kennwort bei korrekter Anmeldung mit dem neuen Hash (dem) gespeichert wird Auf diese Weise stellen Sie sicher, dass ein authentifizierter Benutzer das System verwendet und nur die Benutzer, die sich bis zum Ende des Supportdatums überhaupt nicht anmelden, ihre Kennwörter zurücksetzen. Und das _old style_ Flag könnte bis zum _end of support_ Datum verschwunden sein.
@MikeOunsworth Ich stimme voll und ganz zu. In der Vergangenheit habe ich einige handgerollte Methoden zum Schutz von Passwörtern gesehen, deren Umkehrung trivial ist. Ich hätte klarer sein und sagen sollen, dass dies umkehrbar und trivial (kostengünstig) ist.
Ich gehe davon aus, dass Sie für # 3 "Alle Passwörter erneut aufbereiten" anstelle von "Alle Passwörter zurücksetzen" sagen wollten.
Option 3 ist die beste - wenn richtig implementiert. Wie [diese ältere Antwort] (http://security.stackexchange.com/a/103403/47143) zeigt, ist es jedoch einfach, subtile, aber sehr schwerwiegende Sicherheitslücken einzuführen. Option 2 ist einfacher zu finden und nicht schlecht.
Warum möchten Sie auch "bcrypt" verwenden? Heutzutage sollten Sie "argon2" verwenden, das den Passwort-Hashing-Wettbewerb gewonnen hat ...
@wb9688 Ich würde Argon2 noch nicht verwenden, zu neu für meinen Geschmack. Ich bevorzuge entweder bcrypt oder scrypt.
Sechs antworten:
Mike Ounsworth
2016-03-21 19:14:27 UTC
view on stackexchange narkive permalink

Ihre Option 1. ist eine schlechte Idee: Zusätzlich zu den von Ihnen angegebenen Gründen für Benutzererfahrung / Öffentlichkeitsarbeit geben Sie Angreifern ein Fenster, in dem sie die Token zum Zurücksetzen von Kennwörtern abfangen und jedes Konto auf Ihrem Server gefährden können. Es löst Ihr Problem auch nicht, wenn Sie auch nur einen Benutzer haben, der zu faul ist, sich anzumelden / sein Passwort zu aktualisieren.

Auf den ersten Blick scheinen mir sowohl 2. als auch 3. in Ordnung zu sein. Ihre Nummer 2 ist nicht weniger sicher als das, was Sie jetzt tun, aber 2. würde bedeuten, dass Sie das derzeit schwache Login für immer unterstützen müssen (oder etwas wie "Nach X Monaten löschen wir Ihr Passwort und zwingen Sie dazu) eine Wiederherstellung ", die die gewünschte Benutzertransparenz unterbricht. Ignorieren wir das also.

Betrachten wir den Fall, in dem sich Benutzer in der Datenbank befinden, die sich nie wieder anmelden werden. Sowohl mit 2. als auch mit 3. müssen Sie die aktuelle Hashing-Alge in Ihrer Codebasis für immer unterstützen, nur für den Fall, dass sie sich anmelden, aber mindestens 3. hat den Vorteil, dass sie (oder besser Sie) geschützt sind Offline-Brute-Force-Angriffe, falls Ihre Datenbank jemals gestohlen wird.

Da Sie die Spalte "Old Style Flag" für immer behalten müssen, tun Sie sich selbst einen Gefallen und machen Sie sie zu einem int kein bool , damit Sie, falls Sie Ihr Passwort-Hashing-Alg jemals erneut aktualisieren müssen, aufzeichnen können, auf welchem ​​ alten Stil sie sich befinden.


UPDATE: Eine sehr ähnliche Frage wurde hier gestellt und baut auf der Diskussion aus diesem Thread auf.

+1 für Ihren letzten Absatz. Darauf habe ich in meiner Antwort verzichtet.
Der letzte Absatz ist eine Prämie wert. Nicht, dass ich einen geben könnte, also habe ich anstelle von virtuellen Internetpunkten meine Gefühle.
"Betrachten wir den Fall, dass Sie Benutzer in der Datenbank haben, die sich nie wieder anmelden werden." - In vielen Fällen wird dies jedoch durch eine andere empfohlene Vorgehensweise abgedeckt: Dieses Konto wird nach einer bestimmten Zeit ohnehin gesperrt, sodass Sie die Unterstützung für den alten Algorithmus nach dieser Zeit einstellen können.
Sie müssen den alten Algorithmus nicht auf unbestimmte Zeit beibehalten. Wenn sich ein Benutzer 12 Monate lang nicht anmeldet, müssen Sie ihn nicht auffordern, sein Kennwort zurückzusetzen. Es besteht eine gute Chance, dass er es bereits vergessen hat
@Mindwin: Natürlich können Sie ein Kopfgeld geben, zögern Sie nicht.
@SilverlightFox zum Zeitpunkt der Veröffentlichung konnte ich nicht, aber ich stellte eine gut aufgenommene Frage und bekam einige virtuelle Punkte.Aber ich denke, ich werde die Seile hocharbeiten, bevor ich anfange, mit solchen High-End-Werkzeugen zu spielen.XD
TTT
2016-03-21 20:10:40 UTC
view on stackexchange narkive permalink

Wenn Sie Option 3 ausführen können, verstehe ich nicht, warum Sie die anderen überhaupt in Betracht ziehen würden. Es ist bei weitem die beste Option. Bei dieser Option wäre es mein Bauchgefühl, zwei verschiedene Salze zu verwenden, eines für den alten Algorithmus und eines für das neue mit bcrypt. Ich stelle mir eine Einrichtung wie diese vor:

  1. Richten Sie Ihr neues Kennwortsystem so ein, wie Sie es heute tun würden.
  2. Erstellen Sie eine neue separate Tabelle mit Feldern für Benutzername (oder ID), Hashing-Algorithmus (Name oder ID), Salt.
  3. Überprüfen Sie beim Anmelden, ob der Benutzer einen Datensatz in der separaten Tabelle hat, und wenn ja, hacken Sie das Kennwort auf die alte Weise. Hashing dann das Ergebnis auf neue Weise und vergleiche es mit dem bcrypt-Hash. Wenn es übereinstimmt, salzen / hashen Sie das Passwort auf die neue Weise neu und löschen Sie den Datensatz aus der separaten Tabelle.
  4. ol>

    Der Nachteil ist, dass Sie das Passwort einige Male im Speicher behalten müssen Millisekunden länger (wen interessiert das?) und Sie haben die zusätzliche Tabellensuche bei jedem Login, so ziemlich für immer, bis entweder die separate Tabelle leer ist oder bis alte Konten so alt werden, dass Sie bereit sind, von ihnen zu verlangen, dass sie ihr Passwort selbst zurücksetzen.

"mit zwei Salzen"? Für jeden Datensatz in der Datenbank sollte es einen geben. Salt sollte nicht von allen Datensätzen mit demselben Hashing-Schema geteilt werden.
@BenVoigt - Natürlich. Ich bezog mich darauf, nicht das gleiche Salz (pro Benutzer) für den alten und den neuen Hash zu verwenden.
@TTT: Ist das nicht irrelevant? Sie haben zu jedem Zeitpunkt nur einen * Hash * im OP-Schema (alter Hash des Passworts, neuer Hash des alten Hash des Passworts oder neuer Hash des Passworts), sodass Sie sowieso nicht mehr als ein Salt benötigen.
@MatthieuM. - Wahrscheinlich ja. Deshalb habe ich es ein "Bauchgefühl" genannt. Es basiert auf der Theorie, dass doppeltes Hashing mit verschiedenen Algorithmen die Entropie verringern kann. Ich glaube, ich habe das extrapoliert und mich gefragt, ob der alte Algorithmus irgendwie mit dem neuen verwandt ist. Könnte das Teilen des Salzes irgendwie zusätzliche Informationen liefern? Wir machen: F2 (salt2, F1 (salt1, pass)). Gibt es für eine unbekannte Funktion 1, wenn salt1 = salt2, trotzdem weitere Informationen? Wahrscheinlich nicht, aber ich weiß nicht, wie ich es definitiv beweisen soll, also mein "Bauchgefühl".
AMADANON Inc.
2016-03-22 06:01:40 UTC
view on stackexchange narkive permalink

Beachten Sie, dass Sie, wenn Ihr ALTES Schema mit Salz gehasht wird, das Schema Nr. 3 nur verwenden können, wenn Sie das Salz SEPARAT speichern.

Normalerweise wird das Salz zusammen mit dem Hash gespeichert. und Sie verwenden das Salz als Eingabe für die Hash-Funktion. Wenn Sie nicht genau dasselbe Salz verwenden, erhalten Sie eine völlig andere Ausgabe.

Wenn Sie newhash (oldsalt + oldhash, newsalt), dann Selbst wenn Sie das richtige Passwort haben, können Sie Oldhash nicht neu erstellen (da Sie kein Oldsalt haben) und Sie können den endgültigen Hash nicht generieren. Gleiches gilt für alle Parameter (z. B. hat bcrypt einen "Kosten" -Parameter - dieser muss beim Verschlüsseln festgelegt und in die Ausgabe eingebettet werden, damit das Kennwort überprüft werden kann).

AUCH : Wenn Sie, wie von anderen erwähnt, speichern, dass der Hash "alt" oder "neu" ist, sollten Sie stattdessen das "Schema" speichern - wobei z 0 ist das "alte" und 1 ist bcrypt (Hinweis, ich verwende nicht "neu" - es ist jetzt "neu", wird nicht für immer "neu" sein!). Ein üblicher Weg, dies zu tun, besteht darin, am Anfang des Hashs einen Marker zu haben (dies kann bereits der Fall sein!). bcrypt verwendet eines der folgenden Standardpräfixe: "$ 2a $", "$ 2b $", "$ 2x" oder "$ 2y $". Abhängig von den möglichen Ausgaben Ihres "alten" Algorithmus müssen Sie möglicherweise Ihr eigenes Präfix erstellen, um diese zu markieren, oder Sie können mit "alles, was nicht mit" $ "beginnt, ist der alte Algorithmus davonkommen.

Und schließlich, da Sie offensichtlich (zu Recht!) mit der Sicherheit der alten Passwörter befasst sind, würde ich vorschlagen, alle zu zwingen, ihr Passwort zu ändern, indem Sie ihnen Anweisungen per E-Mail mit einem Token senden (NICHT! SENDEN) Ein Link! Sie möchten nicht, dass Ihre Benutzer auf einen Link klicken! Sagen Sie ihnen einfach, dass sie sich an der üblichen Stelle anmelden sollen. Fragen Sie dann nach dem Token UND dem Passwort. Andernfalls kann jemand, der in der Vergangenheit ein Passwort gestohlen hat, das Passwort ändern und ein gültiges "neues" Passwort erhalten.

ENDLICH: Verfallsdatum - Wenn Kennwörter bis zu diesem Datum nicht geändert werden, sollten sie ungültig werden. Dieses Datum sollte in der E-Mail stehen und nicht zu weit in der Zukunft liegen (eine Woche? Hängt davon ab, wie lange Ihre Kunden brauchen, um zu antworten). Danach müssen sie die Prozeduren zum Zurücksetzen des Passworts durchlaufen.

Serge Ballesta
2016-03-22 21:30:16 UTC
view on stackexchange narkive permalink

Ich weiß nicht, wie Ihr Passwortkodierungsschema aussieht, aber wenn es nicht so schlimm ist, ist es wahrscheinlich, dass die Struktur des Passworts im alten und neuen Format unterschiedlich ist.

Ich habe bereits etwas gesehen So wie in einem alten BSD-System, als das System von einer herkömmlichen Kennwortkodierung zu einer sichereren geändert wurde. Die neue begann mit einer Zeichenfolge, die im alten Schema nicht vorhanden sein konnte. Jedes Mal, wenn ein Benutzer mit einem alten Kennwort angemeldet war, wurde sein Klartextkennwort mit der alten Methode überprüft und stillschweigend erneut gehasht und in der Kennwortdatenbank mit gespeichert die neue Methode. Nach einem Monat war kein altes Passwort in der Datenbank vorhanden, ohne dass der Endbenutzer etwas bemerkte.

Das würde irgendwo zwischen Ihrer zweiten und dritten Methode liegen.

Ich weiß das in einer realen Produktionswebsystem können die Dinge jetzt viel schlimmer sein, da Benutzer Wochen oder sogar Monate warten können, bevor sie wieder eine Verbindung herstellen. Aber (abhängig von der tatsächlichen Aktivität) kann es durch die Tatsache gemildert werden, dass ein Benutzer, der seit mehreren Monaten keine Verbindung mehr hergestellt hat, sein Passwort vergessen haben kann - oder Sie können ihm sagen, dass er es getan hat ... Das bedeutet, dass ich etwas warten würde länger hier wahrscheinlich 3 oder 6 Monate und nach dieser Zeit würde ich alle alten Passwörter auf einen verbotenen Wert zurücksetzen und den Benutzer zwingen, sein Passwort bei der nächsten Verbindung zurückzusetzen ... über den Bildschirm vergessenes Passwort .

Die schönen Dinge hier sind:

  • transparent für normale Benutzer
  • keine Änderung des Datenbankschemas - vorausgesetzt, das Kennwortfeld kann beide Stile akzeptieren

Der Nachteil ist, dass Sie gezwungen sind, beide Authentifizierungsmethoden und eine automatische Aktualisierung aller gleichzeitig zu implementieren Stil Passwort.

Eric
2016-03-22 04:07:25 UTC
view on stackexchange narkive permalink

Sie haben die von Ihnen verwendete Sprache nicht erwähnt. Php hat Probleme mit verschiedenen Funktionen, die false zurückgeben sollten, wenn es in einigen Fällen true zurückgeben sollte, oder mit anderen Funktionen, die so klingen, als würden sie die Arbeit erledigen, aber nicht über die Logik verfügen, um tatsächlich die vollständig möglichen gültigen möglichen Eingaben zu verarbeiten > Aber dies ist der richtige Weg, um das zu tun, wovon Sie in PHP sprechen, auch wenn Sie kein PHP verwenden. Der High-Level-Code kann Ihnen einen Ausgangspunkt für die Codierung für Ihre Zwecke geben.

http://php.net/manual/en/function.password-needs-rehash.php

  $ password = 'rasmuslerdorf'; $ hash = '$ 2y $ 10 $ YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w / oLR / jfHsiQwCqTS'; // Der Kostenparameter kann sich im Laufe der Zeit ändern, wenn sich die Hardware verbessert options = array ('cost' = > 11); // Gespeicherten Hash anhand des Klartext-Passworts überprüfen (password_verify ($ password, $ hash)) {// Überprüfen Sie, ob ein neuerer Hashing-Algorithmus verfügbar ist // oder sich die Kosten geändert haben if (password_needs_rehash ($ hash, PASSWORD_DEFAULT, $ options)) {// Wenn ja, erstellen Sie einen neuen Hash und ersetzen Sie den alten $ newHash = password_hash ($ password, PASSWORD_DEFAULT, $ options); } // Benutzer anmelden}  

Was ich tun würde, wäre Ihre Nummer 2 mit dem, was mit einem int erwähnt wurde. Beim Lesen der Dokumentation zu PASSWORD_DEFAULT kann sich dies ändern, wenn bessere Algorithmen gefunden werden und diese aus Unsicherheitsgründen entfernt werden müssen, wenn PHP aktualisiert wird.

Ich habe meine Fragensprache absichtlich agnostisch gehalten, da die Implementierung keine Rolle spielt. Ich weigere mich, PHP zu berühren, aber andere finden dies möglicherweise in Zukunft nützlich?
Micheal Johnson
2016-03-21 21:01:15 UTC
view on stackexchange narkive permalink

Informieren Sie die Benutzer über die Sicherheitslücken im alten Authentifizierungssystem und schlagen Sie vor, dass sie ihr Kennwort ändern / zurücksetzen, um das neue Authentifizierungssystem zu verwenden. Wenn einige Benutzer nach einer festgelegten Zeitspanne (auf die die Benutzer möglicherweise im "Kleingedruckten" irgendwo hingewiesen werden) ihr Kennwort noch nicht geändert / zurückgesetzt haben, deaktivieren Sie ihr Konto und senden Sie ihnen eine E-Mail mit Anweisungen aktiviere es erneut. Auf diese Weise haben Ihre regulären Benutzer das Gefühl, dass sie "aufgefordert" werden, ihr Passwort zu ändern, und nicht "aufgefordert" werden, ihr Passwort zu ändern. Daher ist es unwahrscheinlich, dass sie negativ auf die Anfrage reagieren, selbst wenn sie ihr Passwort ändern (was sie hoffentlich tun werden) , wenn Ihre Beratungs-E-Mail überzeugend genug ist) und Sie das alte Authentifizierungssystem für die wenigen Benutzer, die nie dazu gekommen sind, ihr Passwort zu ändern, nicht für immer unterstützen müssen.

Ich bin mit diesem Rat nicht einverstanden, hauptsächlich wegen der Nachteile, auf die OP bereits in Bezug auf Option 1 hingewiesen hat, und auch wegen derer, auf die Mike O in seiner Antwort hingewiesen hat.
Als Randnotiz stimme ich auch Ihrer Wahl des Ausdrucks "Sicherheitslücken" nicht zu. Ich würde nicht einmal auf dem Server gespeicherte Nur-Text-Passwörter als "Sicherheitslücke" bezeichnen. Obwohl ich es eine extrem schlechte Praxis nennen würde.
@ttt Obwohl beim Aktualisieren des Kennwortmechanismus kein einfacher Text ein Problem darstellt, wissen Sie, was Sie für den verschlüsselten Hash tun müssen.
@TTT Deshalb verwende ich nicht "Option 1"; Ich verwende einen Kompromiss, der in der Praxis wie Option 1 funktioniert, aber nicht die gleichen Auswirkungen auf Benutzer hat.
@MichealJohnson - wahr, ich denke, Sie könnten Ihren Vorschlag "Option 1.5" nennen, aber er hat immer noch die Nachteile von Option 1 - lässt den Eindruck entstehen, dass ein Sicherheitsproblem und / oder eine Sicherheitsverletzung vorliegt, und bietet das Fenster für das Abfangen von Token, wie von Mike O beschrieben und führt sogar ein neues Problem ein: Es könnte die Aufmerksamkeit von Angreifern auf sich ziehen, und jetzt müssen sie versuchen, etwas zu hacken. Wenn sie Zugriff auf den Server erhalten, müssen sie die schwächeren Kennwort-Hashes ausnutzen. (Das wäre nicht möglich, wenn Sie tatsächlich Option 1 hätten.)
@TTT Woher wissen Angreifer, welche Konten schwächere Passwörter haben? Aus Sicht eines Angreifers auf der Frontend-Seite des Servers sind die Passwörter nicht weniger oder sicherer, da sie immer noch brutal erzwungen werden müssten. Wenn der Angreifer die Hashes erhält, können Passwörter kompromittiert werden. Damit dies funktioniert, muss der Angreifer ein Konto auf dem Server registriert haben, die Hashes vom Server stehlen und dann wissen, welche Kennwörter welche Hashes verwenden.
@MichealJohnson - Ich stimme Ihnen zu. Denken Sie daran, dass der Hash-Algorithmus zunächst nur für den Fall geändert werden muss, dass der Server kompromittiert wird. Auf dem Server sollte sich etwas befinden, das angibt, welcher Hashing-Algorithmus verwendet werden soll, damit der Code weiß, welchen er versuchen soll (und der Angreifer ihn auch sehen kann). Wenn Sie keinen Indikator haben, bedeutet dies, dass der Code beide Algorithmen ausprobieren müsste, aber dann wäre der Hash von einem ein gültiges Passwort für den anderen. Einzelheiten dazu finden Sie in Kasperds Kommentar zur Frage.


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...