it-swarm.com.de

Wie erstelle ich ein Token zum Zurücksetzen des Passworts?

Ich habe lange gesucht und nie wirklich Artikel oder Beiträge gefunden, die vollständig erklären, wie ein Token zum Zurücksetzen von Passwörtern erstellt werden sollte.

Was ich bisher weiß:

  • Es sollte zufällig sein.
  • Sein Hash sollte in der Datenbank gespeichert werden.
  • Es sollte nach einiger Zeit ablaufen.

Worüber ich mir nicht sicher bin:

  1. Sollte ich eine kryptografische Methode verwenden, um das zufällige Token zu erstellen? Ist Knoten crypto.randomBytes genug?
  2. Sollte ich eine kryptografische Methode (z. B. bcrypt) verwenden, um das Token zu hashen?
  3. Sollte ich bestimmte Informationen (d. H. Ablaufzeit, UUID usw.) in das Token aufnehmen? Wenn ja, ist JWT ein guter Weg?

Ich stelle mir vor, der ganze Prozess würde ungefähr so ​​aussehen:

  1. Erstellen Sie ein zufälliges Token.
  2. Hash das Token und speichere den Hash in der Datenbank.
  3. Senden Sie das Token im Klartext an den Client.
  4. Sobald es verwendet wird oder wenn es nach einer bestimmten Zeit nicht mehr verwendet wird, löschen Sie es aus der Datenbank.
  5. Wenn ein Token verwendet wird, überprüfen Sie, ob sein Hash mit einem aus der Datenbank übereinstimmt.
  6. Wenn dies übereinstimmt, lassen Sie den Benutzer das Kennwort zurücksetzen. Andernfalls lassen Sie den Vorgang nicht zu.
5
yqlim

Token zum Zurücksetzen von Passwörtern sind Passwörtern nicht sehr ähnlich. Sie sind kurzlebig, zum Einmalgebrauch und - am relevantesten hier - maschinengeneriert und nicht einprägsam.

  1. Sie müssen unbedingt einen kryptografisch sicheren Zufallszahlengenerator verwenden, um das Token zu erstellen. crypto.randomBytes ist gut genug, ja. Stellen Sie sicher, dass der Token lang genug ist. etwas in der Größenordnung von 16 Bytes (128 Bit) sollte funktionieren.
  2. Da das "Vorbild" (der Wert, der in die Hash-Funktion eingegeben wird, in diesem Fall das Token) zufällig ist, muss kein langsamer Hash verwendet werden. Langsame Hashes dienen dem Brute-Force-Schutz, da Passwörter nicht funktionieren und normalerweise nicht lange (maschinell) erraten werden müssen. 128-Bit-Zufallswerte sind für keine praktische Bedeutung des Begriffs brutal zwingbar. Machen Sie einfach eine einzelne Runde SHA-256 oder ähnliches.
  3. Schlechte Idee; es macht die Dinge nur komplizierter. Speichern Sie all diese Dinge stattdessen in der Datenbank. Ja, Sie könnten es zustandslos tun, indem Sie es in ein JWT einfügen, aber die DB macht viel mehr Sinn:
    • Sie müssen ohnehin mit der Datenbank interagieren, um das Kennwort zurückzusetzen.
    • Sie müssen ohnehin das Caching umgehen. Selbst wenn Sie ein verteiltes System haben, müssen alle diese Änderung sehen, damit es keinen Sinn macht, sie zustandslos zu machen.
    • Sie müssen nur einen DB-Lesevorgang durchführen, um das Token zu überprüfen (sowohl, dass sein Wert korrekt ist als auch, dass er noch nicht abgelaufen ist, was in einer einzigen Abfrage durchgeführt werden kann). Dies ist ein relativ seltenes Ereignis. Es ist nicht so, dass bei jeder Anforderung eine Sitzungstoken-Suche durchgeführt werden muss.
    • JWTs haben einen Ablauf, aber es gibt keine bequeme Möglichkeit, sie zum einmaligen Gebrauch zu machen (Sie müssen den Status "Diese JWTs sind nicht mehr gültig" auf dem Server speichern, bis jeder abläuft, wodurch der Punkt von JWTs verfehlt wird.) Token zum Zurücksetzen des Kennworts In der Datenbank gespeicherte Daten können (und sollten) einmalig verwendet werden, indem sie bei der Überprüfung gelöscht werden.
    • Wenn Sie möchten, können Sie eine Bereinigungsaufgabe ausführen, die abgelaufene Token (die nie verwendet wurden) regelmäßig entfernt. Sie belegen jedoch nicht so viel Speicherplatz in der Datenbank (ein Hash-Digest und ein Zeitstempel für jeden Benutzer, wenn Sie nur einen pro Benutzer gleichzeitig gültig haben möchten, oder einen Hash-Digest, einen Zeitstempel und einen Fremdschlüssel in die Benutzertabelle, wenn Sie zulassen möchten, dass mehrere Token gleichzeitig für einen Benutzer gültig sind (beide haben Vor- und Nachteile).
    • JWTs weisen mehr potenzielle Schwachstellen auf (jemand stiehlt Ihren Signaturschlüssel, jemand entdeckt, dass der Schlüssel unsicher generiert und seit der Behebung des Fehlers nicht gedreht wurde, Ihre JWT-Bibliothek ist anfällig für Schlüssel- oder Algorithmusverwirrung usw.) als nur das Überprüfen die DB (die im Grunde genommen für nichts außer SQLi anfällig ist, denke ich, was Sie hoffentlich vermeiden können).

Ihr grundlegender Prozess macht Sinn.

4
CBHacking

1. Ja, Sie sollten eine kryptografische Methode verwenden, um das Token zu generieren. Verwenden Sie immer kryptografische Zufälligkeit, wenn Sie etwas tun, das mit Sicherheit zu tun hat. Ja, crypto.randomBytes ist gut. Verwenden Sie 16 Bytes (Sie könnten mit etwas weniger davonkommen, aber gehen Sie kein Risiko ein, es sei denn, das Token muss unbedingt eingegeben werden, anstatt nur angeklickt oder kopiert zu werden). (16 Bytes entsprechen 24 Zeichen von Base64 oder 32 hexadezimalen Ziffern.)

2. Hash das Token mit einem kryptografischen Hash wie SHA-256 oder SHA-512. Sie benötigen hier keinen Passwort-Hash: Passwort-Hashes wie bcrypt sind für den Fall gedacht, dass die Eingabe ein Passwort ist, an das sich ein Mensch erinnert, und sind nutzlos, wenn die Eingabe eine zufällig generierte Zeichenfolge mit ausreichend weniger ist. Ein Passwort-Hash ist etwas schwieriger zu verwenden und viel langsamer, und Sie brauchen hier keinen.

3. Ich sehe keinen Vorteil darin, Informationen zum Token hinzuzufügen. Informationen wie das Ablaufdatum und der Zweck des Tokens müssen ohnehin in der Datenbank enthalten sein.