it-swarm.com.de

Sichern Sie Hash und Salt für PHP Passwörter

Es wird derzeit gesagt, dass MD5 teilweise unsicher ist. In Anbetracht dessen würde ich gerne wissen, welcher Mechanismus für den Passwortschutz verwendet werden soll.

Diese Frage, Ist "doppeltes Hashing" eines Passworts weniger sicher als nur einmaliges Hashing? legt nahe, dass das mehrmalige Hashing eine gute Idee sein kann, während Wie implementiert man einen Passwortschutz für einzelne Dateien?) schlägt vor, Salz zu verwenden.

Ich benutze PHP. Ich möchte ein sicheres und schnelles Passwort-Verschlüsselungssystem. Das millionenfache Hashing eines Passworts kann sicherer, aber auch langsamer sein. Wie erreicht man ein gutes Gleichgewicht zwischen Geschwindigkeit und Sicherheit? Außerdem würde ich es vorziehen, wenn das Ergebnis eine konstante Anzahl von Zeichen hat.

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

Soll ich auch zwei Felder in der Datenbank speichern (eines mit MD5 und eines mit SHA zum Beispiel)? Würde es sicherer oder unsicherer machen?

Für den Fall, dass ich nicht klar genug war, möchte ich wissen, welche Hashing-Funktion (en) verwendet werden sollen und wie man ein gutes Salz auswählt, um einen sicheren und schnellen Passwortschutzmechanismus zu erhalten.

Verwandte Fragen, die meine Frage nicht ganz abdecken:

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

1131
luiscubal

HAFTUNGSAUSSCHLUSS: Diese Antwort wurde 2008 verfasst.

Seitdem hat uns PHP password_hash und password_verify gegeben, und seit ihrer Einführung sind sie das empfohlene Kennwort-Hashing & Prüfmethode.

Die Theorie der Antwort ist jedoch immer noch gut zu lesen.

TL; DR

Nicht

  • Begrenzen Sie nicht, welche Zeichen Benutzer für Kennwörter eingeben können. Das machen nur Idioten.
  • Beschränken Sie nicht die Länge eines Passworts. Wenn Ihre Benutzer einen Satz mit supercalifragilisticexpialidocious darin wünschen, hindern Sie sie nicht, ihn zu verwenden.
  • Entfernen oder entziehen Sie HTML- und Sonderzeichen nicht dem Kennwort.
  • Speichern Sie das Passwort Ihres Benutzers niemals im Klartext.
  • Schicken Sie Ihrem Benutzer niemals ein Passwort per E-Mail, es sei denn, er hat sein Passwort verloren und Sie haben ein vorübergehendes Passwort gesendet.
  • Protokollieren Sie niemals Passwörter auf irgendeine Weise.
  • Hash niemals Passwörter mit SHA1 oder MD5 oder sogar SHA256! Moderne Cracker können 60 bzw. 180 Milliarden Hashes/Sekunde überschreiten.
  • Mischen Sie nicht bcrypt und mit derrawAusgabe von hash () , verwenden Sie entweder die hexadezimale Ausgabe oder base64_encode. (Dies gilt für alle Eingaben, die möglicherweise einen falschen _\0_ enthalten, wodurch die Sicherheit erheblich beeinträchtigt werden kann.)

DOS

  • Verwenden Sie Scrypt, wenn Sie können. bcrypt wenn du nicht kannst.
  • Verwenden Sie PBKDF2, wenn Sie mit SHA2-Hashes weder bcrypt noch scrypt verwenden können.
  • Setzen Sie alle Kennwörter zurück, wenn die Datenbank gefährdet ist.
  • Implementieren Sie eine vernünftige Mindestlänge von 8 bis 10 Zeichen und setzen Sie mindestens 1 Großbuchstaben, 1 Kleinbuchstaben, eine Zahl und ein Symbol voraus. Dies verbessert die Entropie des Passworts und erschwert das Knacken. (Weitere Informationen finden Sie im Abschnitt "Was macht ein gutes Passwort aus?".)

Warum Hash-Passwörter überhaupt?

Das Ziel beim Hashing von Kennwörtern ist einfach: Verhindern Sie den böswilligen Zugriff auf Benutzerkonten, indem Sie die Datenbank kompromittieren. Das Ziel von Passwort-Hashing ist es, einen Hacker oder Cracker davon abzuhalten, zu viel Zeit oder Geld für die Berechnung der Klartext-Passwörter aufzuwenden. Und Zeit/Kosten sind die besten Abschreckungsmittel in Ihrem Arsenal.

Ein weiterer Grund, warum Sie einen guten, robusten Hash für Benutzerkonten wünschen, besteht darin, dass Sie genügend Zeit haben, um alle Kennwörter im System zu ändern. Wenn Ihre Datenbank gefährdet ist, benötigen Sie genügend Zeit, umleastdas System zu sperren, wenn Sie nicht jedes Kennwort in der Datenbank ändern.

Jeremiah Grossman, CTO von Whitehat Security, in seinem Blog angegeben nach einer kürzlichen Passwortwiederherstellung, die ein gewaltsames Aufheben seines Passwortschutzes erforderlich machte:

Interessanterweise habe ich in diesem Albtraum viel über das Knacken, Speichern und die Komplexität von Passwörtern gelernt.Ich habe begriffen, warum die Speicherung von Passwörtern immer wichtiger ist als die Komplexität von Passwörtern. Wenn Sie nicht wissen, wie Ihr Passwort gespeichert ist, können Sie sich wirklich nur auf Komplexität verlassen. Dies ist für Passwort- und Krypto-Profis möglicherweise allgemein bekannt, für den durchschnittlichen InfoSec- oder Web Security-Experten jedoch sehr bezweifel es.

(Betonung meiner.)

Was macht eingutesPasswort überhaupt aus?

Entropie . (Nicht, dass ich Randalls Standpunkt voll und ganz unterschreibe.)

Kurz gesagt, Entropie ist, wie viel Variation im Passwort enthalten ist. Wenn ein Passwort nur aus lateinischen Kleinbuchstaben besteht, sind das nur 26 Zeichen. Das ist nicht viel Abwechslung. Alphanumerische Passwörter sind mit 36 ​​Zeichen besser. Groß- und Kleinschreibung mit Symbolen sind jedoch ungefähr 96 Zeichen. Das ist viel besser als nur Buchstaben. Ein Problem ist, dass wir Muster einfügen, um unsere Passwörter zu speichern, wodurch die Entropie verringert wird. Hoppla!

Die Passwortentropie ist ngefähr leicht. Die Verwendung des gesamten Bereichs von ASCII-Zeichen (ungefähr 96 typisierbare Zeichen) ergibt eine Entropie von 6,6 pro Zeichen, was mit 8 Zeichen für ein Kennwort für zukünftige Sicherheit immer noch zu niedrig ist (52,679 Bit Entropie). Aber die gute Nachricht ist: Längere Passwörter und Passwörter mit Unicode-Zeichen erhöhen die Entropie eines Passworts und erschweren das Knacken.

Auf der Seite Crypto StackExchange wird die Kennwortentropie länger erörtert. Eine gute Google-Suche wird auch viele Ergebnisse bringen.

In den Kommentaren sprach ich mit @popnoodles, der darauf hinwies, dasserzwingeneine Passwortrichtlinie mit X Länge mit X vielen Buchstaben, Zahlen, Symbolen usw. tatsächlich die Entropie reduzieren kann das Passwortschema vorhersehbarer zu machen. Ich stimme zu. Zufälligkeit, so zufällig wie möglich, ist immer die sicherste, aber denkwürdigste Lösung.

Soweit ich es beurteilen konnte, ist das beste Passwort der Welt ein Catch-22. Entweder ist es nicht einprägsam, zu vorhersehbar, zu kurz, zu viele Unicode-Zeichen (auf einem Windows/Mobile-Gerät schwer einzugeben), zu lang usw. Kein Passwort ist für unsere Zwecke wirklich gut genug, daher müssen wir es so schützen, als ob sie es wären waren in Fort Knox.

Empfohlene Vorgehensweise

Bcrypt und scrypt sind die aktuellen Best Practices. Scrypt wird in der Zeit besser sein als bcrypt, aber es wurde weder von Linux/Unix noch von Webservern als Standard akzeptiert, und es wurden noch keine gründlichen Überprüfungen seines Algorithmus veröffentlicht. Dennoch sieht die Zukunft des Algorithmus vielversprechend aus. Wenn Sie mit Ruby arbeiten, gibt es ein Scrypt Gem , das Ihnen hilft, und Node.js hat jetzt ein eigenes Scrypt -Paket. Sie können Scrypt in PHP entweder über die Erweiterung Scrypt oder die Erweiterung Libsodium verwenden (beide sind in PECL verfügbar).

Ich empfehle dringend, die Dokumentation für die Verschlüsselungsfunktion zu lesen, wenn Sie verstehen möchten, wie man bcrypt verwendet, oder wenn Sie sich eine guteWrapper suchen oder etwas verwenden möchten wie PHPASS für eine ältere Implementierung. Ich empfehle mindestens 12 Runden Bcrypt, wenn nicht 15 bis 18.

Ich habe meine Meinung über die Verwendung von bcrypt geändert, als ich erfuhr, dass bcrypt nur den Schlüsselzeitplan von blowfish mit einem Mechanismus für variable Kosten verwendet. Mit letzterem können Sie die Kosten für die Erzwingung eines Passworts erhöhen, indem Sie den ohnehin teuren Zeitplan für Blowfish erhöhen.

Durchschnittliche Praktiken

Ich kann mir diese Situation fast nicht mehr vorstellen. PHPASS unterstützt PHP 3.0.18 bis 5.3, daher kann es in fast jeder nur vorstellbaren Installation verwendet werden - und sollte verwendet werden, wenn Sie dies nicht tunsicher wissendass Ihre Umgebung bcrypt unterstützt.

Angenommen, Sie können bcrypt oder PHPASS überhaupt nicht verwenden. Was dann?

Versuchen Sie eine Implementierung von PDKBF2 mit maximale Anzahl von Runden , die Ihre Umgebung/Anwendung/Benutzerwahrnehmung tolerieren kann. Die niedrigste Zahl, die ich empfehlen würde, ist 2500 Runden. Stellen Sie außerdem sicher, dass Sie hash_hmac () verwenden, wenn dies verfügbar ist, um die Reproduzierbarkeit der Operation zu erschweren.

Zukünftige Praktiken

PHP 5.5 ist eine vollständige Kennwortschutzbibliothek , die alle Probleme bei der Arbeit mit bcrypt beseitigt. Während die meisten von uns mit PHP 5.2 und 5.3 in den meisten gängigen Umgebungen, insbesondere auf gemeinsam genutzten Hosts, nicht weiterkommen, hat @ircmaxell eine Kompatibilitätsebene für die kommende API erstellt, die abwärtskompatibel zu _ ist.PHP 5.3.7.

Cryptography Recap & Haftungsausschluss

Die Rechenleistung, die erforderlich ist, umcrackein gehashtes Passwort zu erstellen, existiert nicht. Die einzige Möglichkeit für Computer, ein Kennwort zu "knacken", besteht darin, es neu zu erstellen und den Hash-Algorithmus zu simulieren, der zum Sichern des Kennworts verwendet wird. Die Geschwindigkeit des Hash hängt linear von seiner Fähigkeit ab, brutal gezwungen zu werden. Schlimmer noch, die meisten Hash-Algorithmen können problemlos parallelisiert werden, um eine noch schnellere Leistung zu erzielen. Aus diesem Grund sind kostspielige Schemata wie bcrypt und scrypt so wichtig.

Sie können möglicherweise nicht alle Bedrohungen oder Angriffswege vorhersehen und müssen sich daher bemühen, Ihre Benutzer im Voraus zu schützen . Wenn Sie dies nicht tun, verpassen Sie möglicherweise sogar die Tatsache, dass Sie angegriffen wurden, bis es zu spät ist ...und Sie haften. Um dies zu vermeiden, sollten Sie zunächst paranoid handeln. Greifen Sie Ihre eigene Software (intern) an und versuchen Sie, Benutzeranmeldeinformationen zu stehlen oder die Konten anderer Benutzer zu ändern oder auf deren Daten zuzugreifen. Wenn Sie die Sicherheit Ihres Systems nicht testen, können Sie nur sich selbst die Schuld geben.

Zum Schluss: Ich bin kein Kryptograf. Was auch immer ich gesagt habe, ist meine Meinung, aber ich denke, es basiert auf gesundem Menschenverstand ... und viel Lesen. Denken Sie daran, seien Sie so paranoid wie möglich, machen Sie es so schwer wie möglich, sich einzumischen, und wenden Sie sich an einen White-Hat-Hacker oder Kryptografen, um zu erfahren, was er über Ihren Code/Ihr System aussagt.

957
Robert K

Eine viel kürzere und sicherere Antwort - Schreiben Sie überhaupt keinen eigenen Passwortmechanismus , verwenden Sie einen bewährten Mechanismus.

  • PHP 5.5 oder höher: password_hash () ist von guter Qualität und Teil des PHP -Kerns.
  • Ältere PHP Versionen: Die phpass Bibliothek von OpenWall ist viel besser als die meisten benutzerdefinierten Codes - verwendet in WordPress, Drupal usw.

Die meisten Programmierer verfügen einfach nicht über das Fachwissen, um kryptobezogenen Code sicher zu schreiben, ohne Sicherheitslücken einzuführen.

Schneller Selbsttest: Was ist Passwort-Stretching und wie viele Iterationen sollten Sie verwenden? Wenn Sie die Antwort nicht kennen, sollten Sie password_hash() verwenden, da die Kennworterweiterung aufgrund der viel schnelleren CPUs und der Verwendung von GPUs und FPGAs zum Knacken jetzt ein kritisches Merkmal von Kennwortmechanismen ist Passwörter mit Raten von Milliarden von Vermutungen pro Sekunde (mit GPUs).

Zum Beispiel können Sie alle 8-stelligen Windows-Kennwörter in 6 Stunden knacken 25 GPUs verwenden, die auf 5 Desktop-PCs installiert sind. Dies ist brachial, d. H. Auflisten und Überprüfen jedes 8-stelligen Windows-Kennworts , einschließlich Sonderzeichen, und ist kein Wörterbuchangriff. Das war im Jahr 2012, ab 2018 konnte man weniger GPUs verwenden oder mit 25 GPUs schneller knacken.

Es gibt auch viele Rainbow-Table-Angriffe auf Windows-Kennwörter, die auf normalen CPUs ausgeführt werden und sehr schnell sind. All dies liegt daran, dass Windows immer noch nicht salzen oder strecken seine Passwörter, auch in Windows 1 - nicht machen der gleiche Fehler wie bei Microsoft!

Siehe auch:

  • ausgezeichnete Antwort mit mehr darüber, warum password_hash() oder phpass der beste Weg sind.
  • guter Blog-Artikel Angabe der empfohlenen Arbeitsfaktoren (Anzahl der Iterationen) für die Hauptalgorithmen einschließlich bcrypt, scrypt und PBKDF2.
132
RichVel

Ich würde den Passwort-Hash nicht auf zwei verschiedene Arten speichern, da das System dann mindestens so schwach ist wie der schwächste der verwendeten Hash-Algorithmen.

42
Tom Haigh

Ab PHP 5.5 verfügt PHP über einfache, sichere Funktionen zum Hashing und Überprüfen von Passwörtern, password_hash () und password_verify ()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

Wenn password_hash() verwendet wird, generiert es ein zufälliges Salt und bezieht es in den ausgegebenen Hash ein (zusammen mit den Kosten und dem verwendeten Algorithmus). password_verify() liest dann diesen Hash und bestimmt die verwendete Salt- und Verschlüsselungsmethode. und überprüft es anhand des bereitgestellten Klartext-Passworts.

Wenn Sie PASSWORD_DEFAULT angeben, wird PHP angewiesen, den Standard-Hashing-Algorithmus der installierten PHP-Version zu verwenden. Welcher Algorithmus dies bedeutet, soll sich in zukünftigen Versionen im Laufe der Zeit ändern, sodass er immer einer der stärksten verfügbaren Algorithmen sein wird.

Wenn Sie die Kosten erhöhen (die Standardeinstellung ist 10), wird das Brute-Force-Verfahren schwieriger, aber Sie müssen auch Hashes generieren und Passwörter überprüfen, um die CPU Ihres Servers zu entlasten.

Beachten Sie, dass, obwohl sich der Standard-Hashing-Algorithmus ändern kann, alte Hashes weiterhin einwandfrei überprüft werden, da der verwendete Algorithmus im Hash gespeichert ist und password_verify() darauf zugreift.

36

Obwohl die Frage beantwortet wurde, möchte ich nur wiederholen, dass die für das Hashing verwendeten Salze zufällig sein und nicht der E-Mail-Adresse entsprechen sollten, wie sie in der ersten Antwort vorgeschlagen wurde.

Weitere Erklärungen finden Sie unter http://www.pivotalsecurity.com/blog/password-hashing-salt-should-it-be-random/

Kürzlich hatte ich eine Diskussion, ob mit zufälligen Bits gesalzene Passwort-Hashes sicherer sind als die mit erratenen oder bekannten Salzen gesalzenen. Mal sehen: Wenn das System, auf dem das Passwort gespeichert ist, sowie das System, auf dem das zufällige Salt gespeichert ist, kompromittiert sind, hat der Angreifer sowohl Zugriff auf Hash als auch auf Salt. Es spielt also keine Rolle, ob das Salt zufällig ist oder nicht. Der Angreifer kann vorberechnete Rainbow-Tabellen generieren, um den Hash zu knacken. Hier kommt der interessante Teil - es ist nicht so einfach, vorberechnete Tabellen zu generieren. Nehmen wir ein Beispiel für das Sicherheitsmodell WPA. Ihr WPA Passwort wird tatsächlich nie an den Wireless Access Point gesendet. Stattdessen wird es mit Ihrer SSID (dem Netzwerknamen wie Linksys, Dlink usw.) gehasht. Eine sehr gute Erklärung, wie das funktioniert, finden Sie hier. Um ein Passwort aus dem Hash abzurufen, müssen Sie das Passwort sowie Salt (Netzwerkname) kennen. Church of Wifi hat bereits Hash-Tabellen mit den besten 1000 SSIDs und etwa 1 Million Passwörtern vorberechnet. Die Größe aller Tische beträgt ca. 40 GB. Wie Sie auf ihrer Website nachlesen können, hat jemand drei Tage lang 15 FGPA-Arrays verwendet, um diese Tabellen zu erstellen. Angenommen, das Opfer verwendet die SSID als "a387csf3" und das Passwort als "123456". Wird sie von diesen Tabellen geknackt? Nein! .. es kann nicht. Auch wenn das Passwort schwach ist, enthalten die Tabellen keine Hashes für die SSID a387csf3. Das ist das Schöne daran, zufälliges Salz zu haben. Es wird Cracker abschrecken, die auf vorberechneten Tabellen gedeihen. Kann es einen entschlossenen Hacker aufhalten? Wahrscheinlich nicht. Die Verwendung von zufälligen Salzen bietet jedoch eine zusätzliche Schutzschicht. Während wir uns mit diesem Thema befassen, wollen wir den zusätzlichen Vorteil diskutieren, zufällige Salze in einem separaten System zu speichern. Szenario 1: Kennwort-Hashes werden auf System X gespeichert, und die für das Hashing verwendeten Salt-Werte werden auf System Y gespeichert. Diese Salt-Werte sind erraten oder bekannt (z. B. Benutzername). Szenario 2: Kennwort-Hashes werden auf System X gespeichert und Salt-Werte für Hashes werden auf System Y gespeichert. Diese Salzwerte sind zufällig. Wenn System X kompromittiert wurde, gibt es, wie Sie sich vorstellen können, einen großen Vorteil, wenn Sie Zufallssalz auf einem separaten System verwenden (Szenario 2). Der Angreifer muss Additionswerte erraten, um Hashes knacken zu können. Wenn ein 32-Bit-Salt verwendet wird, können für jedes erratene Kennwort 2 ^ 32 = 4.294.967.296 (ca. 4,2 Milliarden) Iterationen erforderlich sein.

32
Gaurav Kumar

Ich möchte nur darauf hinweisen, dass PHP 5.5 eine Passwort-Hashing-API enthält, die einen Wrapper um crypt() bereitstellt. Diese API vereinfacht die Aufgabe des Hashens, Verifizierens und erneuten Aufbereitens von Kennwort-Hashes erheblich. Der Autor hat auch ein Kompatibilitätspaket (in Form einer einzelnen password.php-Datei, die Sie einfach require verwenden) für Benutzer von PHP 5.3 veröffentlicht. 7 und später und möchte dies jetzt verwenden.

Derzeit wird nur BCRYPT unterstützt, es soll jedoch problemlos um andere Kennwort-Hashing-Techniken erweitert werden. Da die Technik und die Kosten als Teil des Hashs gespeichert werden, werden durch Änderungen an Ihrer bevorzugten Hashing-Technik/den Kosten die aktuellen Hashes und das Framework nicht ungültig wird automatisch die richtige Technik/Kosten bei der Validierung verwenden. Es behandelt auch das Erzeugen 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 Hash 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 überprüfen, ob der Hash mit Ihrer aktuellen Technik/Ihrem aktuellen Kostenschema übereinstimmt
  • password_verify() - Überprüft, ob ein Passwort mit einem Hash übereinstimmt

Momentan 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 Releases ändern kann, wenn neuere, stärkere Hashing-Algorithmen unterstützt werden." Durch die Verwendung von PASSWORD_DEFAULT und password_needs_rehash () beim Anmelden (und ggf. erneutes Aufbereiten) sollte sichergestellt werden, dass Ihre Hashes für Brute-Force-Angriffe mit wenig oder gar keiner Arbeit angemessen belastbar sind.

EDIT: Mir ist gerade aufgefallen, dass dies in der Antwort von Robert K kurz erwähnt wird. Ich werde diese Antwort hier lassen, da ich denke, dass sie ein bisschen mehr Informationen über die Funktionsweise und die Benutzerfreundlichkeit für diejenigen bietet, die die Sicherheit nicht kennen.

26
JonoCoetzee

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

Standardmäßig wurde die stärkste verfügbare Verschlüsselung verwendet, die in Phpass implementiert ist. Dabei handelt es sich um bcrypt und es wird auf andere Verschlüsselungen bis hinunter zu MD5 zurückgegriffen, um eine Abwärtskompatibilität mit Frameworks wie Wordpress zu gewährleisten.

Der zurückgegebene Hash kann unverändert in der Datenbank gespeichert werden. Beispiel für die Generierung von Hash ist:

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

Um das Passwort zu bestätigen, können Sie Folgendes verwenden:

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

Dinge, an die man sich erinnern sollte

Über die Kennwortverschlüsselung für PHP ist viel gesagt worden, von denen die meisten sehr gute Ratschläge sind. Bevor Sie jedoch überhaupt mit der Verwendung von PHP für die Kennwortverschlüsselung beginnen, stellen Sie sicher, dass die folgenden implementiert sind oder implementiert werden können .

SERVER

PORTS

Egal wie gut Ihre Verschlüsselung ist, wenn Sie den Server, auf dem PHP und DB ausgeführt werden, nicht ordnungsgemäß sichern, sind alle Ihre Bemühungen wertlos. Die meisten Server funktionieren relativ gleich, ihnen sind Ports zugewiesen, über die Sie per FTP oder Shell remote auf sie zugreifen können. Stellen Sie sicher, dass Sie den Standardport der jeweils aktiven Remoteverbindung ändern. Wenn Sie dies nicht tun, haben Sie den Angreifer dazu gebracht, einen Schritt weniger auf Ihr System zuzugreifen.

BENUTZERNAME

Verwenden Sie für alles Gute auf der Welt nicht den Benutzernamen admin, root oder ähnliches. Auch wenn Sie auf einem Unix-basierten System arbeiten, sollten Sie das Root-Konto NICHT zugänglich machen. Es sollte immer nur Sudo sein.

PASSWORT

Sie weisen Ihre Benutzer an, gute Passwörter zu erstellen, um nicht gehackt zu werden. Tun Sie dasselbe. Worum geht es, wenn Sie sich die Mühe machen, Ihre Haustür zu verriegeln, wenn die Hintertür weit geöffnet ist?.

DATABASE

SERVER

Idealerweise möchten Sie Ihre DB und APPLICATION auf separaten Servern. Dies ist aus Kostengründen nicht immer möglich, bietet jedoch ein gewisses Maß an Sicherheit, da der Angreifer zwei Schritte ausführen muss, um uneingeschränkt auf das System zugreifen zu können.

USER

Lassen Sie Ihre Anwendung immer über ein eigenes Konto verfügen, um auf die Datenbank zuzugreifen, und geben Sie ihr nur die Berechtigungen, die sie benötigt.

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

Wie immer NICHT diese Wurzel oder ähnliches machen.

PASSWORT

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

PHP

PASSWORT

Speichern Sie NIEMALS ein Passwort in Ihrer Datenbank, sondern speichern Sie den Hash und das eindeutige Salz. Ich werde später erklären, warum.

HASHING

ONE WAY HASHING !!!!!!!, Hash niemals ein Passwort auf eine Weise, dass es rückgängig gemacht werden kann. Hashes sollten eine Möglichkeit sein, das heißt, dass Sie sie nicht rückgängig machen und mit dem Passwort vergleichen, sondern stattdessen das eingegebene Passwort hashen auf die gleiche Weise und vergleichen Sie die beiden Hashes. Dies bedeutet, dass ein Angreifer selbst dann, wenn er Zugriff auf die Datenbank erhält, nicht weiß, wie das tatsächliche Kennwort lautet, sondern nur den daraus resultierenden Hash. Dies bedeutet mehr Sicherheit für Ihre Benutzer im schlimmsten Fall.

Es gibt viele gute Hashing-Funktionen (password_hash, hash, etc ...), aber Sie müssen einen guten Algorithmus auswählen, damit der Hash wirksam wird. (bcrypt und ähnliche sind anständige Algorithmen.)

Wenn es auf die Geschwindigkeit ankommt, ist die Widerstandsfähigkeit gegen Brute-Force-Angriffe umso höher, je langsamer sie ist.

Einer der häufigsten Fehler beim Hashing ist, dass Hashes nicht nur für die Benutzer gelten. Dies liegt hauptsächlich daran, dass Salze nicht eindeutig erzeugt werden.

SALZEN

Passwörter sollten immer vor dem Hashing gesalzen werden. Salting fügt dem Kennwort eine zufällige Zeichenfolge hinzu, damit ähnliche Kennwörter in der Datenbank nicht gleich erscheinen. Wenn das Salz jedoch nicht für jeden Benutzer einzigartig ist (dh Sie verwenden ein hartkodiertes Salz), haben Sie Ihr Salz so gut wie wertlos gemacht. Denn sobald ein Angreifer ein Passwort-Salt herausgefunden hat, hat er das Salt für alle.

Wenn Sie ein Salt erstellen, vergewissern Sie sich, dass es für das zu salzende Kennwort eindeutig ist, und speichern Sie dann sowohl den abgeschlossenen Hash als auch das Salt in Ihrer Datenbank. Dies bewirkt, dass ein Angreifer jedes Salz und jeden Hasch einzeln knacken muss, bevor er Zugriff erhält. Dies bedeutet für den Angreifer viel mehr Arbeit und Zeit.

BENUTZER, DIE PASSWÖRTER ERSTELLEN

Wenn der Benutzer über das Frontend ein Kennwort erstellt, muss es an den Server gesendet werden. Dies führt zu einer Sicherheitslücke, da das unverschlüsselte Kennwort an den Server gesendet wird und wenn ein Angreifer auf Ihre gesamte Sicherheit in PHP zugreifen kann, ist dies wertlos. Übertragen Sie die Daten IMMER SICHER, dies erfolgt über SSL, aber seien Sie müde, auch wenn SSL nicht fehlerfrei ist (der Heartbleed-Fehler von OpenSSL ist ein Beispiel dafür).

Lassen Sie den Benutzer auch ein sicheres Passwort erstellen, es ist einfach und sollte immer getan werden, der Benutzer wird am Ende dafür dankbar sein.

Unabhängig davon, welche Sicherheitsmaßnahmen Sie ergreifen, ist nichts zu 100% sicher. Je fortschrittlicher die zu schützende Technologie ist, desto fortschrittlicher werden die Angriffe. Das Befolgen dieser Schritte macht Ihre Website jedoch sicherer und für Angreifer weitaus weniger wünschenswert.

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

http://git.io/mSJqpw

13
wmfrancia

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 Zeichen und Zahlen zu beschränken). Je länger Sie sich entscheiden, desto sicherer und langsamer wird es. 64 Bytes sollten in Ordnung sein, denke ich.

12
AticusFinch

Ich habe hier ein perfektes Thema zu diesem Thema gefunden: https://crackstation.net/hashing-security.htm , ich wollte, dass Sie davon profitieren. basierter Angriff auch.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>
8
Jason OOO

Letztendlich bietet Double-Hashing mathematisch keinen Nutzen. In der Praxis ist es jedoch hilfreich, um tabellenbasierte Rainbow-Angriffe zu verhindern. Mit anderen Worten, es ist nicht vorteilhafter als das Hashing mit einem Salz, was in Ihrer Anwendung oder auf Ihrem Server viel weniger Prozessorzeit in Anspruch nimmt.

7
Max

Normalerweise verwende ich SHA1 und Salt mit der Benutzer-ID (oder einer anderen benutzerspezifischen Information), und manchmal verwende ich zusätzlich ein konstantes Salt (also habe ich 2 Teile zum Salt).

SHA1 wird jetzt ebenfalls als etwas kompromittiert angesehen, jedoch in weit geringerem Maße als MD5. Indem Sie ein Salz (ein beliebiges Salz) verwenden, verhindern Sie die Verwendung eines generischen Rainbow-Tabelle , um Ihre Hashes anzugreifen hash). Ein Angreifer könnte möglicherweise eine Rainbow-Tabelle mit Ihrem Salt generieren. Aus diesem Grund sollten Sie ein benutzerspezifisches Salt hinzufügen. Auf diese Weise müssen sie für jeden Datensatz in Ihrem System eine Rainbow-Tabelle generieren, nicht nur für Ihr gesamtes System! Mit dieser Art des Einsalzens ist sogar MD5 anständig sicher.

5
rmeador

SHA1 und ein Salz sollten ausreichen (natürlich abhängig davon, ob Sie etwas für Fort Knox oder ein Anmeldesystem für Ihr System codieren Einkaufsliste) auf absehbare Zeit. Wenn SHA1 für Sie nicht gut genug ist, verwenden Sie SHA256 .

Die Idee eines Salzes ist es, die Hashing-Ergebnisse sozusagen aus dem Gleichgewicht zu bringen. Es ist beispielsweise bekannt, dass der MD5-Hash eines leeren Strings d41d8cd98f00b204e9800998ecf8427e ist. Wenn also jemand mit einem ausreichenden Gedächtnis diesen Hash sehen und wissen würde, dass es sich um den Hash eines leeren Strings handelt. Wenn die Zeichenfolge gesalzen ist (z. B. mit der Zeichenfolge "MY_PERSONAL_SALT"), wird der Hash für die "leere Zeichenfolge" (dh "MY_PERSONAL_SALT") aeac2612626724592271634fb14d3ea6, daher nicht offensichtlich zurückverfolgen. Was ich versuche zu sagen, dass es besser ist, any salt zu verwenden, als nicht zu. Daher ist es nicht allzu wichtig zu wissen, welches welches Salz verwendet werden soll.

Es gibt tatsächlich Websites, die genau dies tun - Sie können einen (md5) -Hash eingeben und einen bekannten Klartext ausspucken, der diesen bestimmten Hash generiert. Wenn Sie Zugriff auf eine Datenbank erhalten würden, in der normale md5-Hashes gespeichert sind, wäre es für Sie trivial, den Hash für den Administrator für einen solchen Dienst einzugeben und sich anzumelden. Wenn jedoch die Kennwörter gesalzen würden, würde ein solcher Dienst werden unwirksam.

Double-Hashing wird allgemein als schlechte Methode angesehen, da es den Ergebnisraum verkleinert. Alle gängigen Hashes haben eine feste Länge. Sie können also nur einen endlichen Wert für diese feste Länge festlegen, und die Ergebnisse variieren nicht mehr so ​​stark. Dies könnte als eine andere Form des Salzens angesehen werden, aber ich würde es nicht empfehlen.

3
Henrik Paul