it-swarm.com.de

Wie kann ich die Passwörter meiner Benutzer sicher speichern?

Wie viel sicherer ist das als einfaches MD5 ? Ich habe gerade mit der Passwortsicherheit begonnen. Ich bin ziemlich neu in PHP.

$salt = 'csdnfgksdgojnmfnb';

$password = md5($salt.$_POST['password']);
$result = mysql_query("SELECT id FROM users
                       WHERE username = '".mysql_real_escape_string($_POST['username'])."'
                       AND password = '$password'");

if (mysql_num_rows($result) < 1) {
    /* Access denied */
    echo "The username or password you entered is incorrect.";
} 
else {
    $_SESSION['id'] = mysql_result($result, 0, 'id');
    #header("Location: ./");
    echo "Hello $_SESSION[id]!";
}
166
Rebar

Der einfachste Weg, Ihr Kennwortspeichersystem sicherer zu machen, ist unter Verwendung einer Standardbibliothek.

Da die Sicherheit in der Regel sehr viel komplizierter ist und mehr unsichtbare Ansteckungsmöglichkeiten bietet, als die meisten Programmierer allein bewältigen könnten, ist die Verwendung einer Standardbibliothek fast immer die einfachste und sicherste (wenn nicht die einzige) Option.


Die neue Kennwort-API PHP (5.5.0 und höher)

Wenn Sie PHP Version 5.5.0 oder neuer verwenden, können Sie die neue vereinfachte Kennwort-Hashing-API verwenden

Beispiel für Code, der die Passwort-API von PHP verwendet:

<?php
// $hash is what you would store in your database
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT, ['cost' => 12]);

// $hash would be the $hash (above) stored in your database for this user
$checked = password_verify($_POST['password'], $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

(Falls Sie noch Version 5.3.7 oder neuer verwenden, können Sie ircmaxell/password_compat installieren, um Zugriff auf die integrierten Funktionen zu erhalten.)


Gesalzene Haschisch verfeinern: Pfeffer hinzufügen

Wenn Sie zusätzliche Sicherheit wünschen, empfehlen die Sicherheitsbeamten (2017) jetzt, ' pepper ' zu den (automatisch) gesalzenen Passworthashes hinzuzufügen. 

Es gibt eine einfache Klasse, die dieses Muster sicher implementiert. Ich empfehle: Netsilik/PepperedPasswords ( github ).
Es wird mit einer MIT Lizenz geliefert, so dass Sie sie auch in proprietären Projekten nach Belieben verwenden können.

Beispiel für Code mit Netsilik/PepperedPasswords:

<?php
use Netsilik/Lib/PepperedPasswords;

// Some long, random, binary string, encoded as hexadecimal; stored in your configuration (NOT in your Database, as that would defeat the entire purpose of the pepper).
$config['pepper'] = hex2bin('012345679ABCDEF012345679ABCDEF012345679ABCDEF012345679ABCDEF');

$hasher = new PepperedPasswords($config['pepper']);

// $hash is what you would store in your database
$hash = $hasher->hash($_POST['password']);

// $hash would be the $hash (above) stored in your database for this user
$checked = $hasher->verify($_POST['password'], $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}


Die ALTE Standardbibliothek

Bitte beachten Sie: Sie sollten dies nicht mehr brauchen! Dies ist nur für historische Zwecke hier.

Sehen Sie sich Folgendes an: Portable PHP - Passwort-Hashing-Framework : phpass und stellen Sie sicher, dass Sie den CRYPT_BLOWFISH-Algorithmus verwenden, sofern dies möglich ist.

Codebeispiel mit phpass (v0.2):

<?php
require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );

// $hash would be the $hash (above) stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

PHPass wurde in einigen bekannten Projekten implementiert:

  • phpBB3
  • WordPress 2.5+ sowie bbPress
  • das Drupal 7-Release (Modul für Drupal 5 & 6 verfügbar)
  • Andere

Das Gute ist, dass Sie sich nicht um die Details kümmern müssen. Diese Details wurden von erfahrenen Personen programmiert und von vielen Leuten im Internet überprüft.

Weitere Informationen zu Kennwortspeichersystemen finden Sie in Jeff `s Blogbeitrag: Sie speichern wahrscheinlich Kennwörter falsch

Was auch immer Sie tun, wenn Sie sich für den Ansatz "ich mache es selbst, danke", , MD5 oder SHA1 nicht mehr verwenden. Sie sind ein Nice-Hash-Algorithmus, werden jedoch als aus Sicherheitsgründen gebrochen betrachtet.

Derzeit ist die Verwendung von crypt mit CRYPT_BLOWFISH die beste Vorgehensweise.
CRYPT_BLOWFISH in PHP ist eine Implementierung des Bcrypt-Hashes. Bcrypt basiert auf der Blowfish-Blockverschlüsselung und nutzt die teure Schlüsseleinrichtung, um den Algorithmus zu verlangsamen.

262
Jacco

Ihre Benutzer sind viel sicherer, wenn Sie parametrisierte Abfragen verwenden, anstatt SQL-Anweisungen zu verketten. Und das Salt sollte für jeden Benutzer eindeutig sein und zusammen mit dem Passwort-Hash gespeichert werden.

28
Anton Gogolev

Ein besserer Weg wäre für jeden Benutzer ein eindeutiges Salz zu haben.

Der Vorteil eines Salt ist, dass es für einen Angreifer schwieriger wird, die MD5-Signatur jedes Wörterbuchworts vorab zu generieren. Wenn ein Angreifer jedoch erfährt, dass Sie über ein festes Salt verfügen, kann er die MD5-Signatur jedes Wörterbuchworts vorab generieren, dem Ihr fixer Salt vorangestellt ist.

Ein besserer Weg ist, jedes Mal, wenn ein Benutzer sein Kennwort ändert, Ihr System einen zufälligen Salt-Wert generiert und diesen Salt mit dem Benutzerdatensatz speichert. Die Überprüfung des Kennworts ist etwas teurer (da Sie erst nach dem Salt suchen müssen, bevor Sie die MD5-Signatur erstellen können), ist es jedoch für Angreifer viel schwieriger, MD5-Dateien vorab zu generieren.

11

Mit PHP 5.5 (was ich beschreibe, steht sogar früheren Versionen zur Verfügung, siehe unten) um die Ecke. Ich möchte vorschlagen, seine neue, integrierte Lösung zu verwenden: password_hash() und password_verify() . Es bietet verschiedene Optionen, um die erforderliche Passwortsicherheit zu erreichen (z. B. durch Angabe eines Parameters "cost" über das Array $options).

<?php
var_dump(password_hash("my-secret-password", PASSWORD_DEFAULT));

$options = array(
    'cost' => 7, // this is the number of rounds for bcrypt
    // 'salt' => 'TphfsM82o1uEKlfP9vf1f', // you could specify a salt but it is not recommended
);
var_dump(password_hash("my-secret-password", PASSWORD_BCRYPT, $options));
?>

wird zurückkehren

string(60) "$2y$10$w2LxXdIcqJpD6idFTNn.eeZbKesdu5y41ksL22iI8C4/6EweI7OK."
string(60) "$2y$07$TphfsM82o1uEKlfP9vf1fOKohBqGVXOJEmnUtQu7Y1UMft1R4D3d."

Wie Sie vielleicht sehen, enthält die Zeichenfolge den Saltwert sowie die in den Optionen angegebenen Kosten. Es enthält auch den verwendeten Algorithmus.

Daher werden bei der Überprüfung des Kennworts (z. B. wenn sich der Benutzer anmeldet) die komplementäre Funktion password_verify() verwendet, um die erforderlichen Verschlüsselungsparameter aus dem Kennwort-Hash selbst zu extrahieren.

Wenn kein Salt angegeben wird, ändert sich der generierte Kennwort-Hash bei jedem Aufruf von password_hash(), da der Salt zufällig generiert wird. Daher schlägt der Vergleich eines vorherigen Hashes mit einem neu generierten Hash fehl, selbst wenn das Kennwort richtig ist.

Überprüfen von Arbeiten wie folgt:

var_dump(password_verify("my-secret-password", '$2y$10$BjHJbMCNWIJq7xiAeyFaHOGaO0jjNoE11e0YAer6Zu01OZHN/gk6K'));
var_dump(password_verify("wrong-password", '$2y$10$BjHJbMCNWIJq7xiAeyFaHOGaO0jjNoE11e0YAer6Zu01OZHN/gk6K'));

var_dump(password_verify("my-secret-password", '$2y$07$TphfsM82o1uEKlfP9vf1fOKohBqGVXOJEmnUtQu7Y1UMft1R4D3d.'));
var_dump(password_verify("wrong-password", '$2y$07$TphfsM82o1uEKlfP9vf1fOKohBqGVXOJEmnUtQu7Y1UMft1R4D3d.'));

Ich hoffe, dass die Bereitstellung dieser integrierten Funktionen bald eine bessere Kennwortsicherheit bei Datendiebstahl zur Verfügung stellt, da dadurch der Gedanke reduziert wird, den der Programmierer in eine ordnungsgemäße Implementierung einlegen muss.

Es gibt eine kleine Bibliothek (eine PHP - Datei), in der Sie den <password_hash von PHP 5.5 in PHP 5.3.7+ erhalten: https://github.com/ircmaxell/ password_compat

11
akirk

Das ist okay für mich. Mr. Atwood schrieb über die Stärke von MD5 gegen Rainbow-Tische , und im Grunde sitzen Sie mit einem solchen langen Salz ziemlich gut (obwohl einige zufällige Satzzeichen/Zahlen es verbessern könnten).

Sie können sich auch SHA-1 anschauen, das in diesen Tagen immer beliebter zu werden scheint.

0
nickf

Ich will hinzufügen:

  • Beschränken Sie die Benutzerkennwörter nicht nach Länge

Aus Gründen der Kompatibilität mit alten Systemen legen Sie häufig eine Begrenzung für die maximale Länge des Kennworts fest. Dies ist eine schlechte Sicherheitsrichtlinie: Wenn Sie eine Einschränkung festlegen, legen Sie diese nur für die Mindestlänge von Kennwörtern fest.

  • Senden Sie keine Benutzerpasswörter per E-Mail

Um ein vergessenes Passwort wiederherzustellen, senden Sie die Adresse, unter der der Benutzer das Passwort ändern kann.

  • Aktualisieren Sie die Hashwerte der Benutzerkennwörter

Der Passwort-Hash kann veraltet sein (Parameter des Algorithmus können aktualisiert werden). Mit der Funktion password_needs_rehash() können Sie es überprüfen.

0
Aleksey Bykov