2011-01-08 6 views
6

Ein paar Jahre habe ich hier auf Stackoverflow gefragt, wie PHP Password Storage sicher zu machen. Die main answer schlägt folgende Hash-Algorithmus:PHP Passwortspeicher mit HMAC + nonce - Ist Nonce Zufälligkeit wichtig?

function hash_password($password, $nonce) { 
    global $site_key; 
    return hash_hmac('sha512', $password . $nonce, $site_key); 
} 

Die Antwort deutet auf eine zufällige nonce verwenden. Gibt es einen Vorteil darin, eine zufällige Nonce über einfache eindeutige Nonces zu haben?

Zum Beispiel kann jeder Benutzer seine eigene ID haben, die sich nicht ändert. Nehmen wir jedoch an, Benutzer-IDs sind sequenziell (mit der automatischen Inkrementierung von MySQL) und daher nicht zufällig. Wäre die Benutzer-ID eine gute Nonce oder ist die Zufälligkeit wichtig?

Jetzt kann jeder Benutzer einen Benutzernamen auswählen. Jeder Benutzer hat seinen eigenen Benutzernamen, der sich nicht ändert, und zwei verschiedene Benutzer können nicht den gleichen Benutzernamen haben. Benutzernamen sind immer noch nicht zufällig, aber sie sind auch nicht sequentiell. Würden Benutzernamen als Nonce gut genug sein? Wäre es besser, als die Benutzer-ID zu verwenden?

+0

Ihre Nonce sollte ein Salz sein. Ein Salz ist per Definition zufällig. Ich habe eine lange Antwort über das Salzen hier geschrieben: http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco

Antwort

2

Das ist alles der Annahme, dass ein NONCE ein Salz ...

Wenn durch nonce Sie ein Salz bedeuten, dann ja, dass mehr Rainbow-Tabellen erfordert gemacht werden. In der Regel reicht es aus, wenn mehr als 20 Zeichen lang sind, aber für extreme Sicherheitsbedingungen möchten Sie ein neues zufälliges Salz für jedes Passwort.

Auch gute Wahl in einem langsamen Hash http://www.php.net/manual/en/function.hash.php#89574, kein Sarkasmus. Aber ich mag reif.

Die untere Hälfte Ihrer Antwort wurde nicht angezeigt. Zur Erläuterung: Nonces werden verwendet, um die Verwendung von Rainbow-Tabellen zu verhindern. Ob die IDs funktionieren, hängt lediglich von der Länge der IDs ab. Zufälligkeit ist technisch nicht wichtig, macht aber mehr Regenbogen-Tabellen erforderlich. Ein Beispiel wäre zum Beispiel, dass Sie ein Zeichen "a" als Nonce verwendet haben und das Passwort 2 Zeichen lang war, eine Rainbow-Tabelle von a-aa, a-ab a-ac und so weiter müsste erstellt werden. Wenn Sie jedes Mal ein zufälliges verwenden, müssten vielleicht alle Permutationen von 'a' gemacht werden + alle Permutationen der anderen zufälligen Zeichen.

Aber im Allgemeinen machen Regenbogen-Tabellen eine ziemlich lange Zeit. Also, wenn Sie mit einem Salz, das lange ist wahrscheinlich ist der Regenbogen-Tisch für es nicht existiert.

+0

Diese Antwort ist richtig, aber hat nichts mit dem zu tun Frage. HMAC ist kein Hash, sondern ein MAC-Algorithmus. Wird auch als Keyed-Hash bezeichnet. Daher ist die Nonce in der Frage nicht der richtige Begriff. Es sollte (privater) Schlüssel sein. Und in diesem Fall ist ein Schlüssel sicher (es sei denn, Sie arbeiten für oder schützen vor einer nationalen Behörde). – Henri

+0

Also der Name "NoviceCoding" ... Vielen Dank für die Erklärung. Ich versuche, das kleine Wissen, das ich über diese Dinge habe, zu teilen, aber wie diesmal war es irrelevant. Danke noch einmal. – NoviceCoding

+0

Ein Salz * muss zufällig sein *. Eine Benutzer-ID ist definitiv nicht für die Verwendung als Salz geeignet: Es gibt viele Systeme mit einer Benutzer-ID 1 (es gibt sogar eine hohe Wahrscheinlichkeit, dass das Administrator-Konto irgendwo in den niedrigen IDs ist). Alles Vorhersagbare schwächt das Schema. – Jacco

0

Für Passwort speichern genug, um zu verwenden:

sha512(salt + password) 

salt sollte zufällig und eindeutig sein für jeden Benutzer. Zufälliges Salt wird den vorberechneten Hash-Tabellen-Angriff unmöglich machen: Jeder Benutzer benötigt seine eigenen berechneten Hash-Tabellen. Wenn Sie nicht zufälliges Salz verwenden, ist die Wahrscheinlichkeit, dass die vorberechnete Tabelle existiert, höher.

Position salt vor dem Passwort hilft Hash-Muster zu verbergen, falls einige Benutzer das gleiche Passwort haben.

Nonce wird nicht benötigt, weil es zur Verhinderung einer Antwort Angriff ist. Dieser Schutz ist in Ihrer Architektur nicht möglich.

Verwendung HMAC Kollisionen zu verhindern, ist nutzlos, da a) wir Hash nicht für MAC verwenden, b) Kollisionswahrscheinlichkeit 50% für SHA-512 zu machen you need to calculate etwa 2^256 Werte.Und 2^256 ist wahrlich astronomische Zahl.

+0

Das ist ein schlechter Rat. HMAC ist der unumstrittene Standard für die Passwortspeicherung, da es extrem ressourcenintensiv bis hin zu Brute-Force ist. Verwenden Sie HMAC + SHA512, wenn Sie SHA verwenden möchten. – mattbasta

2

Ich fand, dass es ein ziemlich nettes Tutorial online zu diesem Thema geschrieben hatte. Ich erinnere mich nicht ganz, wo auf Google ich es gefunden, aber lassen Sie mich sehen, ob ich die Funktion brechen kann nach unten gut genug, um mich, da es direkt vor mir ist ...

Zuerst wird die Funktion, kann es einen Schlüssel erstellen Länge jeder Größe. Ich habe die Freiheit, es ist ziemlich schwer zu kommentieren ...

function pbkdf2($password,$salt,$iter_count = 1500,$key_length = 32,$algorithm = 'sha512') 
{ 
    /* 
     @param string password -- password to be encrypted 
     @param string salt -- salt to encrypt with 
     @param int iter_count -- number of times to iterate blocks 
     @param key_length -- length of key to return 
     @param $algorithm -- algorithm to use in hashing 

     @return string key 
    */ 

    //determine the length of the hahs 
    $hash_length = strlen(hash($algorithm,NULL,TRUE)); 
    //determine the number of key blocks to compute 
    $key_blocks = ceil($key_length/$hash_length); 
    //initialize key 
    $key = ''; 

    //create the key itself 
    //create blocks 
    for($block_count = 1;$block_count <= $key_blocks;$block_count++) 
    { 
     //initalize hash for this block 
     $iterated_block = $block = hash_hmac($algorithm,$salt.pack('N',$block_count),$password,TRUE); 
     //iterate blocks 
     for($iterate = 1;$iterate <= $iter_count;$iterate++) 
     { 
      //xor each iterate 
      $iterated_block ^= ($block = hash_hmac($algorithm,$block,$password,TRUE)); 
     } 
     //append iterated block 
     $key .= $iterated_block; 
    } 
    //return the key 
    return substr($key,0,$key_length); 
} 
  1. Die erste, was sie tut, ist die Länge des Hash herauszufinden.
  2. Als nächstes bestimmt sie, wie viele Schlüsselblöcke werden für die Schlüssellänge erforderlich spezifiziert
  3. Dann initialisiert er den Hash (Key)
  4. Sätze zurückzukehren up der for-Schleife, die jeden Block
  5. nimmt die Anfangs-Hash schaffen des Blocks mit der Blockzähler in binärer zum
  6. beginnt die Schleife den Block $ iter_count mal iteriert (erstellen einer Hash-Wert von selbst)
  7. XOR jedes iterieren und hängen sie iterated_block $ Salz angehängt (xor vorherigen Hash Strom)
  8. XOR-Schleife beendet
  9. append $ iterated_block bis $ Schlüssel für jeden Block
  10. Block Schleife beendet
  11. Rückkehr der Schlüssel

Ich fühle mich ist dies wahrscheinlich der beste Weg, dies zu tun. Vielleicht bin ich zu paranoid?

Verwandte Themen