2014-10-22 16 views
8

Ich bin auf der Suche nach einer einfachen, sicheren Lösung zum Speichern eines Benutzerpasswortes mit Node. Ich bin ein Kryptografie-Neuling, habe aber versucht, eine Lösung aus Online-Recherchen zusammenzustellen. Ich bin auf der Suche nach einer Bestätigung, dass das, was ich mir ausgedacht habe, eine solide Lösung für eine Web-App mit grundlegenden Sicherheitsanforderungen (keine Bank, Krankenhaus usw.) ist. Hier ist sie:Best Practices für die Kryptographie für die Passwortspeicherung in Node

var crypto = require('crypto'); 
var SALT_LENGTH = 64; 
var KEY_LENGTH = 64; 
var ITERATIONS = 1000; 

function createHashedPassword(plainTextPassword, cb) { 
    crypto.randomBytes(SALT_LENGTH, function (err, salt) { 
     console.time('password-hash'); 
     crypto.pbkdf2(plainTextPassword, salt, ITERATIONS, KEY_LENGTH, function (err, derivedKey) { 
      console.timeEnd('password-hash'); 
      return cb(null, {derivedKey: derivedKey, salt: salt, iterations: ITERATIONS}); 
     }); 
    }); 
}; 

... und hier sind die Entscheidungen, die ich gemacht, die mich zu diesem Punkt gebracht:

Welche Hashing-Algorithmus zu benutzen?

Basierend auf this widely referenced article, sieht es aus wie die führenden Konkurrenten PBKDF2, bcrypt und scrypt. Ich habe PBKDF2 gewählt, weil es in Node integriert ist.

Welche Salzgröße verwenden?

10 schien die einfachste Antwort zu sein, die ich finden konnte. Ich weiß immer noch nicht genau, warum 64 Bytes die richtige Salzgröße sind. Wenn ich herum google, bekomme ich andere Stapelaustauschantworten wie this, aber ich bin nicht sicher, dass es auf den Node-Algorithmus zutrifft? Völlig verwirrt hier, eine Erklärung, die auf einen Anfänger zielt, der diese Knotenfunktion verwendet, würde fantastisch sein.

Welche Schlüssellänge zu verwenden?

Noch einmal, basierte ich weitgehend meine Wahl aus the same answer as above, aber ich bin genauso neblig auf die Grundlagen der "warum". Die Antwort besagt, dass es "eine Verschwendung ist, Schlüssel zu erzeugen, die kleiner sind als Ihre Eingabe, also verwenden Sie mindestens 64 Bytes". Hä? Auch hier wäre eine praktische Erklärung hilfreich.

Wie viele Iterationen verwenden?

Für diese Frage habe ich meine Auswahl aus this stack exchange answer basiert. Ich verstehe nicht viel davon, aber ich habe verstanden, dass der Algorithmus ungefähr 8ms dauern soll. Also, wie Sie sehen können, habe ich Timer auf die Funktion gesetzt, und ich habe meine Iterationen angepasst, um es in diesem Ballpark auf meiner Maschine zu bekommen.

Danke!

+0

Wenn es um Sicherheit geht, ist es in der Regel besser auf die gut bekannt zu haften und gut getestete Bibliotheken. Passport.JS kommt Ihnen in den Sinn und es verfügt über Plugins, mit denen Sie Hashing durchführen können. –

+0

Danke @ Pier-LucGendreau. Ich verwende PassportJS, aber es enthält nicht den Code zum Hashing und Speichern von Passwörtern als Teil seiner Bibliothek oder seiner Untermodule. Wenn mir etwas fehlt, lass es mich wissen. – markdb314

+0

Sie können https://github.com/saintedlama/passport-local-mongoose verwenden –

Antwort

6

Das Paket NPM credential behandelt alle diese

Sie das Schreiben bis auf es in dem Buch des Autors sehen Programming Javascript Applications

+0

Ich schaute auf diese Links, und die 'Credential' Paket scheint die gleiche Art von Sache zu tun, die ich oben habe. In seiner Quelle verwendet er eine Salzlänge und Schlüssellänge von 66 Bytes und einen Standardwert von 1000 Iterationen. In der Readme für das Paket sagt er "Das Salz sollte die gleiche Größe wie der Hash haben. Nicht kürzer und nicht mehr". Das sind alles gute Informationen, aber ich würde gerne wenigstens eine grundlegende Erklärung von "Warum" sehen? – markdb314

+0

@ markdb314 Das "warum" würde wahrscheinlich besser erklärt werden von http://security.stackexchange.com/ –

+0

Ja, ich poste es vielleicht ... aber die Antworten gehen normalerweise mehr ins Detail, als ich folgen kann. Ich suche nur jemanden, der mir mit Vertrauen sagt, welche Konstanten zu verwenden sind, und ein einfaches "Warum". – markdb314

2

ich stark BCrypt Verwendung empfehlen würde. Es gibt viele Vorteile für den Algorithmus, und die meisten Implementierungen behandeln all diese Fragen für Sie.

Wie in this answer beschrieben:

Bcrypt hat die beste Art von Ruf, die für einen Verschlüsselungsalgorithmus erreicht werden kann: es ziemlich weit um seit geraumer Zeit verwendet wird, „zog die Aufmerksamkeit“, und bleibt jedoch bis heute ungebrochen.

Ich habe einen ausführlichen Artikel über geschrieben, wie BCrypt in Knoten/ausdrücken sowie andere Rahmenbedingungen hier zu implementieren: http://davismj.me/blog/bcrypt

Verwandte Themen