2009-06-02 11 views
3

Ich bin zu wollen Hash-Passwörter in MySQL speichern, verwende ich PHP:Wie sollten 'rohe binäre Daten' in MySQL gespeichert werden?

<?php 
    $salt = '!£$%^&*()#'; 
    $username = 'abc'; 
    $password = '123'; 
    $hash = hash('sha1', $username . $salt . $password, true); 
?> 

Der wahre Parameter in Hash() den Wert als unformatierte Binärdaten zurück. Aber ich verstehe nicht, was das genau bedeutet. Wie sollte es in MySQL korrekt gespeichert werden?

Antwort

4

Ich fand die Lösung.

Normale (Hex) Hashes von sha1() sind immer CHAR (40) lang. Wenn Sie einen Hash als rohe Binärdaten in PHP zurückgeben, wird eine Zeichenfolge als CHAR (20) zurückgegeben, wodurch 50% Datenbankspeicherplatz gespart wird, der jedoch den exakt gleichen Wert darstellt. Dies liegt daran, dass 2 Zeichen von Hex in 1 Zeichen komprimiert werden können, wodurch der benötigte Platz halbiert wird.

Speichern Sie das Kennwort als CHAR (20) und verwenden Sie die Sortierfolge * _bin.

3

Der letzte Parameter der hash() Funktion gibt an, wie der Hash-Wert zurückgeführt wird:

  • entweder als rohe Binärdaten. Auf diese Weise erhalten Sie die direkte Ausgabe der spezifischen Hash-Funktion, die Sie verwenden, in diesem Fall sha1.
  • Oder als Zeichenfolge, die eine hexadezimale Darstellung der gleichen binären Rohdaten enthält.

Sie sind beide gleich und unterscheiden sich nur in ihrer Darstellung. Wenn Sie keinen guten Grund haben, würde ich vorschlagen, dass Sie die hexadezimale Darstellung verwenden und sie als String in Ihrer Datenbank speichern. Auf diese Weise ist es viel einfacher, Probleme zu debuggen, da Sie den hexadezimalen Hash-Wert einfach ausdrucken können.

-1

Die "normale" Methode, AFAIK, besteht darin, die Funktion addslashes() zu verwenden.

z.B .:

$hash = hash('sha1', $username . $salt . $password, true); 
$query_safe_hash = addslashes($hash); 
$query_safe_username = addslashes($username); 
$query = "INSERT INTO DBTable(username, password) VALUES ('$query_safe_username', '$query_safe_hash')"; 
mysql_query($query) or die("Failed to store credentials!"); 

Randbemerkung: von einem Krypto-Best Practices Standpunkt sollte das Salz eine bekannte Länge sein, sollte zufällig generiert werden, und vorangestellt Ihre Hash vor in der Datenbank gespeichert werden. So etwas wie

$salt = generate_random_salt(); 
$query_safe_hash = addslashes($salt) . addslashes(hash('sha1', $salt . $username . $password, true); 

Dann Anmeldeinformationen des Benutzers, um zu überprüfen, Sie rufen Sie den gespeicherten Hash, entfernen Sie den Hiebe und Streifen die bekannten Salz Länge vom Anfang des gespeicherten Hash und verwendet das gleiche Salz mit einem Hash-Wert der erzeugen Anmeldeinformationen zur Verfügung gestellt, dann vergleichen. Dies hilft, Ihren Hash-Algorithmus gegen verschiedene Kryptoanalyseangriffe (insbesondere differenzielle Kryptoanalyse) zu verhärten.

+0

Korrektur: das Salz muss keine bekannte Länge sein, aber wenn es nicht ist, müssen Sie eine Möglichkeit bereitstellen, es vom Rest des Hashs abzugrenzen. Zum Beispiel, trennen Sie sie durch einen Doppelpunkt oder ein anderes Zeichen, das nicht von Ihrem Hashing Algo erzeugt wird. Das ist potentiell problematisch, wenn Ihr Algorithmus willkürliche Binärdaten erzeugt und Sie nicht die Entropie opfern wollen, also ist die Verwendung eines Salzes bekannter Länge meine bevorzugte Methode. – Dathan

+0

addslashes() schützt nur vor einer Handvoll der vielen SQL-Injection-Methoden. Verwenden Sie vorbereitete Anweisungen oder zumindest mysql_real_escape_string(). –

1

Wenn Sie eine unformatierte binäre Zeichenfolge in MySQL speichern wollen, erklären die Spalte BINARY(16) wenn es einer bekannten festen Länge von 16 Bytes ist, VARBINARY(32) wenn sie auf 32 Bytes variabler Länge ist oben, oder eine der BLOB-Typen für binäre Felder, die möglicherweise sehr lang werden (z. B. BLOB bis zu 64K, LONGBLOB bis zu 4G).

Verwandte Themen