1250 Stimmen

Sicherer Hash und Salt für PHP-Passwörter

Derzeit wird behauptet, dass MD5 teilweise unsicher ist. In Anbetracht dessen würde ich gerne wissen, welchen Mechanismus ich für den Passwortschutz verwenden soll.

Diese Frage, Ist das "doppelte Hashing" eines Passworts weniger sicher als das einmalige Hashing? legt nahe, dass mehrfaches Hashing eine gute Idee sein kann, während Wie kann man einen Passwortschutz für einzelne Dateien einrichten? empfiehlt die Verwendung von Salz.

Ich verwende PHP. Ich möchte ein sicheres und schnelles Passwort-Verschlüsselungssystem. Das millionenfache Hashing eines Passworts ist zwar sicherer, aber auch langsamer. Wie lässt sich ein gutes Gleichgewicht zwischen Geschwindigkeit und Sicherheit erreichen? Außerdem möchte ich, dass das Ergebnis eine konstante Anzahl von Zeichen hat.

  1. Der Hashing-Mechanismus muss in PHP verfügbar sein
  2. Es muss sicher sein
  3. Es kann Salz verwendet werden (sind in diesem Fall alle Salze gleich gut? Gibt es eine Möglichkeit, gute Salze zu erzeugen?)

Sollte ich außerdem zwei Felder in der Datenbank speichern (z. B. eines mit MD5 und ein anderes mit SHA)? Wäre es dadurch sicherer oder unsicherer?

Falls ich mich nicht klar genug ausgedrückt habe, möchte ich wissen, welche Hashing-Funktion(en) zu verwenden sind und wie man einen guten Salt auswählt, um einen sicheren und schnellen Passwortschutzmechanismus zu haben.

Verwandte Fragen, die meine Frage nicht ganz abdecken:

Was ist der Unterschied zwischen SHA und MD5 in PHP?
Einfache Passwortverschlüsselung
Sichere Methoden zur Speicherung von Schlüsseln und Passwörtern für asp.net
Wie würden Sie gesalzene Passwörter in Tomcat 5.5 implementieren?

14 Stimmen

openwall.com/phpass ist auch eine sehr gute Bibliothek

60 Stimmen

Md5 ist jetzt völlig unsicher

3 Stimmen

@NSAwesomeGuy Das hängt davon ab, wofür Sie es verwenden. Es ist trivial, ungesalzene MD5-Passwörter mit Rainbow-Match oder Brute-Force zu knacken, aber mit anständigem Salting ist es immer noch äußerst unpraktisch, eine Rainbow-Tabelle zum schnellen Knacken von Passwortsätzen zu erstellen, und Brute-Force ist ein No-Hoper.

29voto

JonoCoetzee Punkte 989

Ich möchte nur darauf hinweisen, dass PHP 5.5 eine Passwort-Hashing-API die einen Wrapper um crypt() . Diese API vereinfacht das Hashing, die Verifizierung und das Rehashing von Passwort-Hashes erheblich. Der Autor hat auch ein Kompatibilitätspaket (in Form einer einzigen password.php-Datei, die Sie einfach require zu verwenden), für diejenigen, die PHP 5.3.7 und höher verwenden und dies sofort nutzen wollen.

Da die Technik und die Kosten als Teil des Hashes gespeichert werden, werden Änderungen an der von Ihnen bevorzugten Hash-Technik/Kosten die aktuellen Hashes nicht ungültig machen, sondern das Framework wird automatisch die korrekte Technik/Kosten bei der Validierung verwenden. Es übernimmt auch die Generierung eines "sicheren" Salzes, wenn Sie nicht explizit Ihr eigenes definieren.

Die API stellt vier Funktionen zur Verfügung:

  • password_get_info() - gibt Informationen über den angegebenen Hashwert zurück
  • password_hash() - erstellt einen Passwort-Hash
  • password_needs_rehash() - prüft, ob der angegebene Hash mit den angegebenen Optionen übereinstimmt. Nützlich, um zu prüfen, ob der Hash mit Ihrer aktuellen Technik/Ihrem aktuellen Kostenschema übereinstimmt, so dass Sie bei Bedarf einen neuen Hash durchführen können
  • password_verify() - prüft, ob ein Passwort mit einem Hash übereinstimmt

Im Moment akzeptieren diese Funktionen die Passwortkonstanten PASSWORD_BCRYPT und PASSWORD_DEFAULT, die im Moment synonym sind. Der Unterschied besteht darin, dass sich PASSWORD_DEFAULT "in neueren PHP-Versionen ändern kann, wenn neuere, stärkere Hash-Algorithmen unterstützt werden". Die Verwendung von PASSWORD_DEFAULT und password_needs_rehash() bei der Anmeldung (und das Rehashing, falls erforderlich) sollte sicherstellen, dass Ihre Hashes mit wenig bis gar keinem Aufwand für Sie einigermaßen widerstandsfähig gegen Brute-Force-Angriffe sind.

EDIT: Ich habe gerade festgestellt, dass dies in der Antwort von Robert K. kurz erwähnt wird. Ich lasse diese Antwort hier stehen, da ich denke, dass sie ein wenig mehr Informationen über die Funktionsweise und die Benutzerfreundlichkeit für diejenigen bietet, die sich nicht mit Sicherheit auskennen.

21voto

rabudde Punkte 7205

Ich benutze Phpass die eine einfache PHP-Klasse mit einer Datei ist, die sehr einfach in fast jedem PHP-Projekt implementiert werden kann. Siehe auch Das H .

Standardmäßig wird die stärkste verfügbare Verschlüsselung verwendet, die in Phpass implementiert ist, nämlich bcrypt und greift auf andere Verschlüsselungen bis hin zu MD5 zurück, um Abwärtskompatibilität zu Frameworks wie Wordpress zu gewährleisten.

Der zurückgegebene Hash kann unverändert in der Datenbank gespeichert werden. Ein Beispiel für die Erzeugung eines Hashes ist:

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

Um das Passwort zu überprüfen, kann man es verwenden:

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

15voto

wmfrancia Punkte 1226

DINGE, DIE MAN SICH MERKEN SOLLTE

Es wurde schon viel über Passwortverschlüsselung für PHP gesagt, und das meiste davon ist ein sehr guter Rat, aber bevor Sie überhaupt mit der Verwendung von PHP für die Passwortverschlüsselung beginnen, sollten Sie sicherstellen, dass Sie die folgenden Punkte implementiert haben oder bereit sind, sie zu implementieren.

SERVER

PORTEN

Egal wie gut Ihre Verschlüsselung ist, wenn Sie den Server, auf dem PHP und DB laufen, nicht richtig absichern, sind alle Ihre Bemühungen wertlos. Die meisten Server funktionieren relativ gleich: Ihnen sind Ports zugewiesen, über die Sie entweder per FTP oder Shell auf sie zugreifen können. Vergewissern Sie sich, dass Sie den Standardport der aktiven Fernverbindung ändern. Wenn Sie dies nicht tun, haben Sie dem Angreifer einen Schritt weniger abverlangt, um auf Ihr System zuzugreifen.

BENUTZERNAME

Um alles in der Welt sollten Sie nicht den Benutzernamen admin, Root oder etwas Ähnliches verwenden. Auch wenn Sie ein unixbasiertes System verwenden, sollten Sie das Root-Konto NICHT zugänglich machen, sondern immer nur sudo.

PASSWORT

Wenn Sie Ihren Nutzern sagen, dass sie gute Passwörter verwenden sollen, um nicht gehackt zu werden, dann tun Sie das auch. Welchen Sinn hat es, sich die Mühe zu machen, die Vordertür abzuschließen, wenn die Hintertür weit offen steht?

DATENBANK

SERVER

Idealerweise sollten Sie Ihre DB und Ihre ANWENDUNG auf getrennten Servern betreiben. Dies ist aus Kostengründen nicht immer möglich, bietet aber ein gewisses Maß an Sicherheit, da der Angreifer zwei Schritte durchlaufen muss, um vollständig auf das System zuzugreifen.

BENUTZER

Ihre Anwendung sollte immer über ein eigenes Konto für den Zugriff auf die DB verfügen und nur mit den erforderlichen Berechtigungen ausgestattet sein.

Dann haben Sie ein separates Benutzerkonto für sich, das nirgendwo auf dem Server gespeichert ist, auch nicht in der Anwendung.

Wie immer sollte man diese Wurzel oder etwas Ähnliches NICHT machen.

PASSWORT

Befolgen Sie die gleichen Richtlinien wie bei allen guten Passwörtern. Verwenden Sie dasselbe Passwort auch nicht für andere SERVER- oder DB-Konten auf demselben System.

PHP

PASSWORT

Speichern Sie NIEMALS ein Passwort in Ihrer DB, sondern speichern Sie stattdessen den Hash und den eindeutigen Salt, ich werde später erklären, warum.

HASHING

ONE WAY HASHING!!!!!!!, Hashes sollten einseitig sein, d.h. man kehrt sie nicht um und vergleicht sie mit dem Passwort, sondern hasht das eingegebene Passwort auf dieselbe Weise und vergleicht die beiden Hashes. Das bedeutet, dass ein Angreifer, selbst wenn er Zugriff auf die DB erhält, nicht weiß, wie das eigentliche Passwort lautet, sondern nur den daraus resultierenden Hash. Das bedeutet mehr Sicherheit für Ihre Benutzer im schlimmsten Fall.

Es gibt eine Menge guter Hashing-Funktionen ( password_hash , hash etc...), aber Sie müssen einen guten Algorithmus für den Hash auswählen, um effektiv zu sein. (bcrypt und ähnliche Algorithmen sind anständig.)

Wenn es auf die Hash-Geschwindigkeit ankommt, gilt: je langsamer, desto resistenter gegen Brute-Force-Angriffe.

Einer der häufigsten Fehler beim Hashing ist, dass Hashes nicht eindeutig für den Benutzer sind. Das liegt vor allem daran, dass die Salts nicht eindeutig generiert werden.

SALZEN

Passwörter sollten immer erst gesalzen und dann gehasht werden. Beim Salting wird dem Kennwort eine zufällige Zeichenfolge hinzugefügt, damit ähnliche Kennwörter in der DB nicht gleich aussehen. Wenn das Salt jedoch nicht für jeden Benutzer eindeutig ist (d. h. wenn Sie ein fest codiertes Salt verwenden), ist Ihr Salt so gut wie wertlos geworden. Denn sobald ein Angreifer ein Passwort-Salto herausgefunden hat, hat er das Salt für alle anderen Passwörter.

Wenn Sie einen Salt erstellen, stellen Sie sicher, dass er für das zu salzende Passwort eindeutig ist, und speichern Sie dann sowohl den fertigen Hash als auch den Salt in Ihrer DB. Dies führt dazu, dass ein Angreifer jedes Salt und jeden Hash einzeln knacken muss, bevor er sich Zugang verschaffen kann. Das bedeutet für den Angreifer viel mehr Arbeit und Zeit.

BENUTZER, DIE PASSWÖRTER ERSTELLEN

Wenn der Benutzer ein Passwort über das Frontend erstellt, muss es an den Server gesendet werden. Dies stellt ein Sicherheitsproblem dar, da das unverschlüsselte Passwort an den Server gesendet wird und wenn ein Angreifer in der Lage ist, es abzuhören und darauf zuzugreifen, ist die gesamte Sicherheit in PHP wertlos. Übertragen Sie die Daten IMMER SICHER, dies geschieht durch SSL, aber seien Sie vorsichtig, auch SSL ist nicht fehlerfrei (OpenSSLs Heartbleed-Fehler ist ein Beispiel dafür).

Bringen Sie den Benutzer auch dazu, ein sicheres Passwort zu erstellen, das ist einfach und sollte immer gemacht werden, der Benutzer wird am Ende dafür dankbar sein.

Unabhängig von den Sicherheitsmaßnahmen, die Sie ergreifen, ist nichts zu 100 % sicher. Je fortschrittlicher die Technologie zum Schutz ist, desto fortschrittlicher werden die Angriffe. Aber wenn Sie diese Schritte befolgen, wird Ihre Website sicherer und für Angreifer weit weniger begehrenswert.

Hier ist eine PHP-Klasse, die auf einfache Weise einen Hash und ein Salt für ein Passwort erstellt

http://git.io/mSJqpw

1 Stimmen

Sie sollten SHA512 von der Liste der vernünftigen Hash-Algorithmen streichen, da er zu schnell ist. Verwenden Sie ihn nur in Kombination mit PBKDF2. BCrypt basiert zwar auf Blowfish, aber Blowfish selbst ist ein Algorithmus zur Verschlüsselung, nicht zum Hashing.

1 Stimmen

Wie speichern Sie das Zufallssalz in der DB? Ich denke, dass Sie es weder mit einem Hash versehen (kann nicht zur Überprüfung verwendet werden) noch im Klartext speichern (kein wirklicher Nutzen, wenn der Angreifer die DB lesen kann). Also, wie machen Sie es?

0 Stimmen

Wmfrancia schrieb: "Salting fügt dem Passwort eine zufällige Zeichenfolge hinzu, so dass ähnliche Passwörter in der DB nicht gleich aussehen". Das ergibt für mich keinen Sinn. Hashes in der DB erscheinen bereits unähnlich, da dies eine Eigenschaft von Hash-Funktionen ist.

12voto

AticusFinch Punkte 2171

Laut Google ist SHA256 für PHP verfügbar.

Sie sollten auf jeden Fall ein Salz verwenden. Ich würde empfehlen, zufällige Bytes zu verwenden (und sich nicht auf Buchstaben und Zahlen zu beschränken). Wie üblich gilt: Je länger Sie wählen, desto sicherer und langsamer wird es. 64 Bytes sollten in Ordnung sein, denke ich.

13 Stimmen

64 Bit sollten für jeden reichen?

0 Stimmen

@Konerak, ich würde nach 20 Jahren darauf zurückkommen :) Aber ja, SHA256 ist tatsächlich verfügbar. Wenn Sie wissen wollen, wie sicher SHA256 ist, sollten Sie sich das hier ansehen: security.stackexchange.com/questions/90064/

8voto

Max Punkte 1034

Letztendlich bringt das Double-Hashing mathematisch gesehen keinen Vorteil. In der Praxis ist es jedoch nützlich, um Regenbogentabellen-basierte Angriffe zu verhindern. Mit anderen Worten, es bringt keinen größeren Nutzen als das Hashing mit einem Salt, das in Ihrer Anwendung oder auf Ihrem Server viel weniger Rechenzeit benötigt.

2 Stimmen

Mehrfaches Hashing schützt auch vor Wörterbuch- und Brute-Force-Angriffen, d. h. die Berechnung dauert einfach länger.

6 Stimmen

Doppeltes Hashing verschafft Ihnen keinen nennenswerten Vorteil, aber Hashing-Iterationen über mehrere Runden sind immer noch ein praktikabler Schutz gegen Wörterbuch- und Bruce-Force-Angriffe. Industrietaugliche Passwort-Hashes verwenden mehr als 1000 Runden. PKCS#5's PBKDF1 schlägt mindestens 1000 Runden vor.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X