Node.js 如何在mongoDB中存储加密pbkdf2?
我使用以下函数散列用户密码,以下是Express的身份验证示例:Node.js 如何在mongoDB中存储加密pbkdf2?,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我使用以下函数散列用户密码,以下是Express的身份验证示例: function hash(pwd, salt, fn) { // Bytesize var len = 128, // Iterations. ~300ms iterations = 12000; if (3 == arguments.length) { crypto.pbkdf2(pwd, salt, iterations, len, fn); } e
function hash(pwd, salt, fn) {
// Bytesize
var len = 128,
// Iterations. ~300ms
iterations = 12000;
if (3 == arguments.length) {
crypto.pbkdf2(pwd, salt, iterations, len, fn);
} else {
fn = salt;
crypto.randomBytes(len, function(err, salt){
if (err) return fn(err);
salt = salt.toString('base64');
crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
if (err) return fn(err);
fn(null, salt, hash);
});
});
}
}
正如您所看到的,salt
,以base64编码的字符串形式返回。但是,散列
作为慢缓冲返回。该函数还用于在尝试登录用户时比较哈希值
我的Mongoose用户模式指定散列
的类型应为字符串
。这会以一种奇怪的方式存储散列,导致类似这样的内容对我的mongo主机造成严重破坏:
我的问题是,是否有更好/更智能的方法将此散列存储在我的数据库中?我尝试过用.toString('hex')
对其进行编码,还尝试过将用户模式中的哈希类型更改为缓冲区
,但这两种方法都会在尝试登录用户时使所有比较都为假。在myauthenticate
函数中进行了比较,如下所示:
function authenticate(name, pass, fn) {
var findUser = function(username) {
var deferred = Q.defer(),
populateObj = [
// list of paths to populate objects normally goes here
];
User.findOne({ username: name }).populate(populateObj).exec(function (err, retrievedUser) {
if (err || !retrievedUser) {
console.log(err);
deferred.reject('Cannot find user.');
}
else {
deferred.resolve(retrievedUser);
}
});
return deferred.promise;
};
findUser(name).then(function(data) {
// apply the same algorithm to the POSTed password, applying
// the hash against the pass / salt, if there is a match we
// found the user
hash(pass, data.salt, function(err, hash){
if (err) return fn(err);
if (hash == data.hash) return fn(null, data);
return fn('Invalid password.');
});
}, function() {
return fn('Failed to retrieve user.');
});
}
在数据库中将散列存储为十六进制字符串对我来说很好(将它们“原始”存储在字符串
或缓冲区
属性中都不行):
(顺便问一下,crypto.pbkdf2
和crypto.randomBytes
都有同步的对应项)您如何执行实际的比较?您能显示这些的代码吗?@robertklep编辑后添加了authenticate
功能,用于进行比较。当我之前尝试此操作时,我在尝试登录用户时一定没有调用toString('hex')
。另外,我知道它们有同步对应项,我在应用程序的另一部分中使用它们。非常感谢。
var crypto = require('crypto');
var mongoose = require('mongoose');
var client = mongoose.connect('mongodb://localhost/test');
var UserSchema = new mongoose.Schema({
salt : String,
hash : String
});
var User = mongoose.model('User', UserSchema);
hash('secret', function(err, salt, key) {
new User({ salt : salt, hash : key.toString('hex') }).save(function(err, doc) {
User.findById(doc._id, function(err, doc) {
hash('secret', doc.salt, function(err, key) {
console.log('eq', doc.hash === key.toString('hex'));
});
});
});
});